mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-04 21:14:05 +00:00
Continued work on VM update logic
This commit is contained in:
parent
d4dba3713c
commit
6dd3cb454c
@ -103,6 +103,11 @@ func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListRespons
|
|||||||
return nil, errors.New("Not implemented")
|
return nil, errors.New("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RebootVM reboots a virtual machine.
|
||||||
|
func (c *VirtualEnvironmentClient) RebootVM(nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody) error {
|
||||||
|
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/reboot", url.PathEscape(nodeName), vmID), d, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// ShutdownVM shuts down a virtual machine.
|
// ShutdownVM shuts down a virtual machine.
|
||||||
func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody) error {
|
func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody) error {
|
||||||
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil)
|
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil)
|
||||||
@ -154,6 +159,32 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromAgent(nodeName st
|
|||||||
return nil, fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to publish the network interfaces", vmID)
|
return nil, fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to publish the network interfaces", vmID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WaitForNoNetworkInterfacesFromAgent waits for a virtual machine's QEMU agent to unpublish the network interfaces.
|
||||||
|
func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromAgent(nodeName string, vmID int, timeout int, delay int) error {
|
||||||
|
timeDelay := int64(delay)
|
||||||
|
timeMax := float64(timeout)
|
||||||
|
timeStart := time.Now()
|
||||||
|
timeElapsed := timeStart.Sub(timeStart)
|
||||||
|
|
||||||
|
for timeElapsed.Seconds() < timeMax {
|
||||||
|
if int64(timeElapsed.Seconds())%timeDelay == 0 {
|
||||||
|
_, err := c.GetVMNetworkInterfacesFromAgent(nodeName, vmID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
|
timeElapsed = time.Now().Sub(timeStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to unpublish the network interfaces", vmID)
|
||||||
|
}
|
||||||
|
|
||||||
// WaitForState waits for a virtual machine to reach a specific state.
|
// WaitForState waits for a virtual machine to reach a specific state.
|
||||||
func (c *VirtualEnvironmentClient) WaitForState(nodeName string, vmID int, state string, timeout int, delay int) error {
|
func (c *VirtualEnvironmentClient) WaitForState(nodeName string, vmID int, state string, timeout int, delay int) error {
|
||||||
state = strings.ToLower(state)
|
state = strings.ToLower(state)
|
||||||
|
@ -447,6 +447,11 @@ type VirtualEnvironmentVMListResponseData struct {
|
|||||||
ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
|
ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VirtualEnvironmentVMRebootRequestBody contains the body for a VM reboot request.
|
||||||
|
type VirtualEnvironmentVMRebootRequestBody struct {
|
||||||
|
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// VirtualEnvironmentVMShutdownRequestBody contains the body for a VM shutdown request.
|
// VirtualEnvironmentVMShutdownRequestBody contains the body for a VM shutdown request.
|
||||||
type VirtualEnvironmentVMShutdownRequestBody struct {
|
type VirtualEnvironmentVMShutdownRequestBody struct {
|
||||||
ForceStop *CustomBool `json:"forceStop,omitempty,int" url:"forceStop,omitempty,int"`
|
ForceStop *CustomBool `json:"forceStop,omitempty,int" url:"forceStop,omitempty,int"`
|
||||||
|
@ -135,20 +135,20 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMAgentEnabled: {
|
mkResourceVirtualEnvironmentVMAgentEnabled: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
|
||||||
Description: "Whether to enable the QEMU agent",
|
Description: "Whether to enable the QEMU agent",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMAgentEnabled,
|
Default: dvResourceVirtualEnvironmentVMAgentEnabled,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMAgentTrim: {
|
mkResourceVirtualEnvironmentVMAgentTrim: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
|
||||||
Description: "Whether to enable the FSTRIM feature in the QEMU agent",
|
Description: "Whether to enable the FSTRIM feature in the QEMU agent",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMAgentTrim,
|
Default: dvResourceVirtualEnvironmentVMAgentTrim,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMAgentType: {
|
mkResourceVirtualEnvironmentVMAgentType: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The QEMU agent interface type",
|
Description: "The QEMU agent interface type",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMAgentType,
|
Default: dvResourceVirtualEnvironmentVMAgentType,
|
||||||
ValidateFunc: getQEMUAgentTypeValidator(),
|
ValidateFunc: getQEMUAgentTypeValidator(),
|
||||||
},
|
},
|
||||||
@ -176,14 +176,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCDROMEnabled: {
|
mkResourceVirtualEnvironmentVMCDROMEnabled: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
|
||||||
Description: "Whether to enable the CDROM drive",
|
Description: "Whether to enable the CDROM drive",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCDROMEnabled,
|
Default: dvResourceVirtualEnvironmentVMCDROMEnabled,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCDROMFileID: {
|
mkResourceVirtualEnvironmentVMCDROMFileID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The file id",
|
Description: "The file id",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCDROMFileID,
|
Default: dvResourceVirtualEnvironmentVMCDROMFileID,
|
||||||
ValidateFunc: getFileIDValidator(),
|
ValidateFunc: getFileIDValidator(),
|
||||||
},
|
},
|
||||||
@ -212,14 +212,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCloudInitDNSDomain: {
|
mkResourceVirtualEnvironmentVMCloudInitDNSDomain: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The DNS search domain",
|
Description: "The DNS search domain",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCloudInitDNSDomain,
|
Default: dvResourceVirtualEnvironmentVMCloudInitDNSDomain,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitDNSServer: {
|
mkResourceVirtualEnvironmentVMCloudInitDNSServer: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The DNS server",
|
Description: "The DNS server",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCloudInitDNSServer,
|
Default: dvResourceVirtualEnvironmentVMCloudInitDNSServer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -247,14 +247,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address: {
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The IPv4 address",
|
Description: "The IPv4 address",
|
||||||
|
Optional: true,
|
||||||
Default: "",
|
Default: "",
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway: {
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The IPv4 gateway",
|
Description: "The IPv4 gateway",
|
||||||
|
Optional: true,
|
||||||
Default: "",
|
Default: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -273,14 +273,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address: {
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The IPv6 address",
|
Description: "The IPv6 address",
|
||||||
|
Optional: true,
|
||||||
Default: "",
|
Default: "",
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway: {
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The IPv6 gateway",
|
Description: "The IPv6 gateway",
|
||||||
|
Optional: true,
|
||||||
Default: "",
|
Default: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -297,6 +297,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Description: "The user account configuration",
|
Description: "The user account configuration",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
return []interface{}{}, nil
|
return []interface{}{}, nil
|
||||||
},
|
},
|
||||||
@ -304,14 +305,16 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys: {
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Required: true,
|
|
||||||
Description: "The SSH keys",
|
Description: "The SSH keys",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword: {
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The SSH password",
|
Description: "The SSH password",
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCloudInitUserAccountPassword,
|
Default: dvResourceVirtualEnvironmentVMCloudInitUserAccountPassword,
|
||||||
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
|
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
|
||||||
return strings.ReplaceAll(old, "*", "") == ""
|
return strings.ReplaceAll(old, "*", "") == ""
|
||||||
@ -319,8 +322,9 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername: {
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
|
||||||
Description: "The SSH username",
|
Description: "The SSH username",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -329,9 +333,9 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCloudInitUserDataFileID: {
|
mkResourceVirtualEnvironmentVMCloudInitUserDataFileID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Description: "The ID of a file containing custom user data",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The ID of a file containing custom user data",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMCloudInitUserDataFileID,
|
Default: dvResourceVirtualEnvironmentVMCloudInitUserDataFileID,
|
||||||
ValidateFunc: getFileIDValidator(),
|
ValidateFunc: getFileIDValidator(),
|
||||||
},
|
},
|
||||||
@ -360,22 +364,22 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMCPUCores: {
|
mkResourceVirtualEnvironmentVMCPUCores: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The number of CPU cores",
|
Description: "The number of CPU cores",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCPUCores,
|
Default: dvResourceVirtualEnvironmentVMCPUCores,
|
||||||
ValidateFunc: validation.IntBetween(1, 2304),
|
ValidateFunc: validation.IntBetween(1, 2304),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged: {
|
mkResourceVirtualEnvironmentVMCPUHotplugged: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The number of hotplugged vCPUs",
|
Description: "The number of hotplugged vCPUs",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCPUHotplugged,
|
Default: dvResourceVirtualEnvironmentVMCPUHotplugged,
|
||||||
ValidateFunc: validation.IntBetween(0, 2304),
|
ValidateFunc: validation.IntBetween(0, 2304),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets: {
|
mkResourceVirtualEnvironmentVMCPUSockets: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The number of CPU sockets",
|
Description: "The number of CPU sockets",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMCPUSockets,
|
Default: dvResourceVirtualEnvironmentVMCPUSockets,
|
||||||
ValidateFunc: validation.IntBetween(1, 16),
|
ValidateFunc: validation.IntBetween(1, 16),
|
||||||
},
|
},
|
||||||
@ -386,8 +390,8 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDescription: {
|
mkResourceVirtualEnvironmentVMDescription: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The description",
|
Description: "The description",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMDescription,
|
Default: dvResourceVirtualEnvironmentVMDescription,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDisk: &schema.Schema{
|
mkResourceVirtualEnvironmentVMDisk: &schema.Schema{
|
||||||
@ -412,32 +416,32 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID: {
|
mkResourceVirtualEnvironmentVMDiskDatastoreID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Description: "The datastore id",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The datastore id",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskDatastoreID,
|
Default: dvResourceVirtualEnvironmentVMDiskDatastoreID,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskFileFormat: {
|
mkResourceVirtualEnvironmentVMDiskFileFormat: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Description: "The file format",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The file format",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskFileFormat,
|
Default: dvResourceVirtualEnvironmentVMDiskFileFormat,
|
||||||
ValidateFunc: getFileFormatValidator(),
|
ValidateFunc: getFileFormatValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID: {
|
mkResourceVirtualEnvironmentVMDiskFileID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Description: "The file id for a disk image",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The file id for a disk image",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskFileID,
|
Default: dvResourceVirtualEnvironmentVMDiskFileID,
|
||||||
ValidateFunc: getFileIDValidator(),
|
ValidateFunc: getFileIDValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskSize: {
|
mkResourceVirtualEnvironmentVMDiskSize: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
|
Description: "The disk size in gigabytes",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The disk size in gigabytes",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSize,
|
Default: dvResourceVirtualEnvironmentVMDiskSize,
|
||||||
ValidateFunc: validation.IntBetween(1, 8192),
|
ValidateFunc: validation.IntBetween(1, 8192),
|
||||||
},
|
},
|
||||||
@ -462,26 +466,26 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedRead: {
|
mkResourceVirtualEnvironmentVMDiskSpeedRead: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The maximum read speed in megabytes per second",
|
Description: "The maximum read speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedRead,
|
Default: dvResourceVirtualEnvironmentVMDiskSpeedRead,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable: {
|
mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The maximum burstable read speed in megabytes per second",
|
Description: "The maximum burstable read speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedReadBurstable,
|
Default: dvResourceVirtualEnvironmentVMDiskSpeedReadBurstable,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite: {
|
mkResourceVirtualEnvironmentVMDiskSpeedWrite: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The maximum write speed in megabytes per second",
|
Description: "The maximum write speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedWrite,
|
Default: dvResourceVirtualEnvironmentVMDiskSpeedWrite,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable: {
|
mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The maximum burstable write speed in megabytes per second",
|
Description: "The maximum burstable write speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedWriteBurstable,
|
Default: dvResourceVirtualEnvironmentVMDiskSpeedWriteBurstable,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -496,8 +500,8 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMIPv4Addresses: {
|
mkResourceVirtualEnvironmentVMIPv4Addresses: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
|
||||||
Description: "The IPv4 addresses published by the QEMU agent",
|
Description: "The IPv4 addresses published by the QEMU agent",
|
||||||
|
Computed: true,
|
||||||
Elem: &schema.Schema{
|
Elem: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
@ -505,8 +509,8 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMIPv6Addresses: {
|
mkResourceVirtualEnvironmentVMIPv6Addresses: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
|
||||||
Description: "The IPv6 addresses published by the QEMU agent",
|
Description: "The IPv6 addresses published by the QEMU agent",
|
||||||
|
Computed: true,
|
||||||
Elem: &schema.Schema{
|
Elem: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
@ -514,15 +518,15 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMKeyboardLayout: {
|
mkResourceVirtualEnvironmentVMKeyboardLayout: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The keyboard layout",
|
Description: "The keyboard layout",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMKeyboardLayout,
|
Default: dvResourceVirtualEnvironmentVMKeyboardLayout,
|
||||||
ValidateFunc: getKeyboardLayoutValidator(),
|
ValidateFunc: getKeyboardLayoutValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMMACAddresses: {
|
mkResourceVirtualEnvironmentVMMACAddresses: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
|
||||||
Description: "The MAC addresses for the network interfaces",
|
Description: "The MAC addresses for the network interfaces",
|
||||||
|
Computed: true,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMMemory: &schema.Schema{
|
mkResourceVirtualEnvironmentVMMemory: &schema.Schema{
|
||||||
@ -545,22 +549,22 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMMemoryDedicated: {
|
mkResourceVirtualEnvironmentVMMemoryDedicated: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The dedicated memory in megabytes",
|
Description: "The dedicated memory in megabytes",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMMemoryDedicated,
|
Default: dvResourceVirtualEnvironmentVMMemoryDedicated,
|
||||||
ValidateFunc: validation.IntBetween(64, 268435456),
|
ValidateFunc: validation.IntBetween(64, 268435456),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMMemoryFloating: {
|
mkResourceVirtualEnvironmentVMMemoryFloating: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The floating memory in megabytes (balloon)",
|
Description: "The floating memory in megabytes (balloon)",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMMemoryFloating,
|
Default: dvResourceVirtualEnvironmentVMMemoryFloating,
|
||||||
ValidateFunc: validation.IntBetween(0, 268435456),
|
ValidateFunc: validation.IntBetween(0, 268435456),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMMemoryShared: {
|
mkResourceVirtualEnvironmentVMMemoryShared: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
|
||||||
Description: "The shared memory in megabytes",
|
Description: "The shared memory in megabytes",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMMemoryShared,
|
Default: dvResourceVirtualEnvironmentVMMemoryShared,
|
||||||
ValidateFunc: validation.IntBetween(0, 268435456),
|
ValidateFunc: validation.IntBetween(0, 268435456),
|
||||||
},
|
},
|
||||||
@ -571,8 +575,8 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMName: {
|
mkResourceVirtualEnvironmentVMName: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The name",
|
Description: "The name",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMName,
|
Default: dvResourceVirtualEnvironmentVMName,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice: &schema.Schema{
|
mkResourceVirtualEnvironmentVMNetworkDevice: &schema.Schema{
|
||||||
@ -586,20 +590,20 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceBridge: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The bridge",
|
Description: "The bridge",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
|
||||||
Description: "Whether to enable the network device",
|
Description: "Whether to enable the network device",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The MAC address",
|
Description: "The MAC address",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
||||||
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
|
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
|
||||||
return new == ""
|
return new == ""
|
||||||
@ -608,15 +612,15 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceModel: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The model",
|
Description: "The model",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceModel,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceModel,
|
||||||
ValidateFunc: getNetworkDeviceModelValidator(),
|
ValidateFunc: getNetworkDeviceModelValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANIDs: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceVLANIDs: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
|
||||||
Description: "The VLAN identifiers",
|
Description: "The VLAN identifiers",
|
||||||
|
Optional: true,
|
||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
return []interface{}{}, nil
|
return []interface{}{}, nil
|
||||||
},
|
},
|
||||||
@ -629,8 +633,8 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkInterfaceNames: {
|
mkResourceVirtualEnvironmentVMNetworkInterfaceNames: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
|
||||||
Description: "The network interface names published by the QEMU agent",
|
Description: "The network interface names published by the QEMU agent",
|
||||||
|
Computed: true,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNodeName: &schema.Schema{
|
mkResourceVirtualEnvironmentVMNodeName: &schema.Schema{
|
||||||
@ -641,28 +645,29 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMOSType: {
|
mkResourceVirtualEnvironmentVMOSType: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The OS type",
|
Description: "The OS type",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMOSType,
|
Default: dvResourceVirtualEnvironmentVMOSType,
|
||||||
ValidateFunc: getOSTypeValidator(),
|
ValidateFunc: getOSTypeValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMPoolID: {
|
mkResourceVirtualEnvironmentVMPoolID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
|
||||||
Description: "The ID of the pool to assign the virtual machine to",
|
Description: "The ID of the pool to assign the virtual machine to",
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMPoolID,
|
Default: dvResourceVirtualEnvironmentVMPoolID,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMStarted: {
|
mkResourceVirtualEnvironmentVMStarted: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
|
||||||
Description: "Whether to start the virtual machine",
|
Description: "Whether to start the virtual machine",
|
||||||
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMStarted,
|
Default: dvResourceVirtualEnvironmentVMStarted,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMVMID: {
|
mkResourceVirtualEnvironmentVMVMID: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
|
Description: "The VM identifier",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Description: "The VM identifier",
|
|
||||||
Default: dvResourceVirtualEnvironmentVMVMID,
|
Default: dvResourceVirtualEnvironmentVMVMID,
|
||||||
ValidateFunc: getVMIDValidator(),
|
ValidateFunc: getVMIDValidator(),
|
||||||
},
|
},
|
||||||
@ -707,107 +712,15 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
cdromFileID = "cdrom"
|
cdromFileID = "cdrom"
|
||||||
}
|
}
|
||||||
|
|
||||||
var cloudInitConfig *proxmox.CustomCloudInitConfig
|
cloudInitConfig, err := resourceVirtualEnvironmentVMGetCloudConfig(d, m)
|
||||||
|
|
||||||
cloudInit := d.Get(mkResourceVirtualEnvironmentVMCloudInit).([]interface{})
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(cloudInit) > 0 {
|
if cloudInitConfig != nil {
|
||||||
cdromEnabled = true
|
cdromEnabled = true
|
||||||
cdromFileID = "local-lvm:cloudinit"
|
cdromFileID = "local-lvm:cloudinit"
|
||||||
|
|
||||||
cloudInitBlock := cloudInit[0].(map[string]interface{})
|
|
||||||
cloudInitConfig = &proxmox.CustomCloudInitConfig{}
|
|
||||||
cloudInitDNS := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitDNS].([]interface{})
|
|
||||||
|
|
||||||
if len(cloudInitDNS) > 0 {
|
|
||||||
cloudInitDNSBlock := cloudInitDNS[0].(map[string]interface{})
|
|
||||||
domain := cloudInitDNSBlock[mkResourceVirtualEnvironmentVMCloudInitDNSDomain].(string)
|
|
||||||
|
|
||||||
if domain != "" {
|
|
||||||
cloudInitConfig.SearchDomain = &domain
|
|
||||||
}
|
|
||||||
|
|
||||||
server := cloudInitDNSBlock[mkResourceVirtualEnvironmentVMCloudInitDNSServer].(string)
|
|
||||||
|
|
||||||
if server != "" {
|
|
||||||
cloudInitConfig.Nameserver = &server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudInitIPConfig := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfig].([]interface{})
|
|
||||||
cloudInitConfig.IPConfig = make([]proxmox.CustomCloudInitIPConfig, len(cloudInitIPConfig))
|
|
||||||
|
|
||||||
for i, c := range cloudInitIPConfig {
|
|
||||||
configBlock := c.(map[string]interface{})
|
|
||||||
ipv4 := configBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4].([]interface{})
|
|
||||||
|
|
||||||
if len(ipv4) > 0 {
|
|
||||||
ipv4Block := ipv4[0].(map[string]interface{})
|
|
||||||
ipv4Address := ipv4Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address].(string)
|
|
||||||
|
|
||||||
if ipv4Address != "" {
|
|
||||||
cloudInitConfig.IPConfig[i].IPv4 = &ipv4Address
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4Gateway := ipv4Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway].(string)
|
|
||||||
|
|
||||||
if ipv4Gateway != "" {
|
|
||||||
cloudInitConfig.IPConfig[i].GatewayIPv4 = &ipv4Gateway
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv6 := configBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6].([]interface{})
|
|
||||||
|
|
||||||
if len(ipv6) > 0 {
|
|
||||||
ipv6Block := ipv6[0].(map[string]interface{})
|
|
||||||
ipv6Address := ipv6Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address].(string)
|
|
||||||
|
|
||||||
if ipv6Address != "" {
|
|
||||||
cloudInitConfig.IPConfig[i].IPv6 = &ipv6Address
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv6Gateway := ipv6Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway].(string)
|
|
||||||
|
|
||||||
if ipv6Gateway != "" {
|
|
||||||
cloudInitConfig.IPConfig[i].GatewayIPv6 = &ipv6Gateway
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudInitUserAccount := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccount].([]interface{})
|
|
||||||
|
|
||||||
if len(cloudInitUserAccount) > 0 {
|
|
||||||
cloudInitUserAccountBlock := cloudInitUserAccount[0].(map[string]interface{})
|
|
||||||
keys := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys].([]interface{})
|
|
||||||
|
|
||||||
if len(keys) > 0 {
|
|
||||||
sshKeys := make(proxmox.CustomCloudInitSSHKeys, len(keys))
|
|
||||||
|
|
||||||
for i, k := range keys {
|
|
||||||
sshKeys[i] = k.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudInitConfig.SSHKeys = &sshKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
password := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword].(string)
|
|
||||||
|
|
||||||
if password != "" {
|
|
||||||
cloudInitConfig.Password = &password
|
|
||||||
}
|
|
||||||
|
|
||||||
username := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername].(string)
|
|
||||||
|
|
||||||
cloudInitConfig.Username = &username
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudInitUserDataFileID := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID].(string)
|
|
||||||
|
|
||||||
if cloudInitUserDataFileID != "" {
|
|
||||||
cloudInitConfig.Files = &proxmox.CustomCloudInitFiles{
|
|
||||||
UserVolume: &cloudInitUserDataFileID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentVMCPU}, 0, true)
|
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentVMCPU}, 0, true)
|
||||||
@ -989,6 +902,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
KeyboardLayout: &keyboardLayout,
|
KeyboardLayout: &keyboardLayout,
|
||||||
NetworkDevices: networkDeviceObjects,
|
NetworkDevices: networkDeviceObjects,
|
||||||
OSType: &osType,
|
OSType: &osType,
|
||||||
|
PoolID: &poolID,
|
||||||
SCSIDevices: scsiDevices,
|
SCSIDevices: scsiDevices,
|
||||||
SCSIHardware: &scsiHardware,
|
SCSIHardware: &scsiHardware,
|
||||||
SerialDevices: []string{"socket"},
|
SerialDevices: []string{"socket"},
|
||||||
@ -1010,10 +924,6 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
body.Name = &name
|
body.Name = &name
|
||||||
}
|
}
|
||||||
|
|
||||||
if poolID != "" {
|
|
||||||
body.PoolID = &poolID
|
|
||||||
}
|
|
||||||
|
|
||||||
err = veClient.CreateVM(nodeName, body)
|
err = veClient.CreateVM(nodeName, body)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1186,6 +1096,110 @@ func resourceVirtualEnvironmentVMCreateStart(d *schema.ResourceData, m interface
|
|||||||
return resourceVirtualEnvironmentVMRead(d, m)
|
return resourceVirtualEnvironmentVMRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentVMGetCloudConfig(d *schema.ResourceData, m interface{}) (*proxmox.CustomCloudInitConfig, error) {
|
||||||
|
var cloudInitConfig *proxmox.CustomCloudInitConfig
|
||||||
|
|
||||||
|
cloudInit := d.Get(mkResourceVirtualEnvironmentVMCloudInit).([]interface{})
|
||||||
|
|
||||||
|
if len(cloudInit) > 0 {
|
||||||
|
cloudInitBlock := cloudInit[0].(map[string]interface{})
|
||||||
|
cloudInitConfig = &proxmox.CustomCloudInitConfig{}
|
||||||
|
cloudInitDNS := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitDNS].([]interface{})
|
||||||
|
|
||||||
|
if len(cloudInitDNS) > 0 {
|
||||||
|
cloudInitDNSBlock := cloudInitDNS[0].(map[string]interface{})
|
||||||
|
domain := cloudInitDNSBlock[mkResourceVirtualEnvironmentVMCloudInitDNSDomain].(string)
|
||||||
|
|
||||||
|
if domain != "" {
|
||||||
|
cloudInitConfig.SearchDomain = &domain
|
||||||
|
}
|
||||||
|
|
||||||
|
server := cloudInitDNSBlock[mkResourceVirtualEnvironmentVMCloudInitDNSServer].(string)
|
||||||
|
|
||||||
|
if server != "" {
|
||||||
|
cloudInitConfig.Nameserver = &server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudInitIPConfig := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfig].([]interface{})
|
||||||
|
cloudInitConfig.IPConfig = make([]proxmox.CustomCloudInitIPConfig, len(cloudInitIPConfig))
|
||||||
|
|
||||||
|
for i, c := range cloudInitIPConfig {
|
||||||
|
configBlock := c.(map[string]interface{})
|
||||||
|
ipv4 := configBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4].([]interface{})
|
||||||
|
|
||||||
|
if len(ipv4) > 0 {
|
||||||
|
ipv4Block := ipv4[0].(map[string]interface{})
|
||||||
|
ipv4Address := ipv4Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address].(string)
|
||||||
|
|
||||||
|
if ipv4Address != "" {
|
||||||
|
cloudInitConfig.IPConfig[i].IPv4 = &ipv4Address
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4Gateway := ipv4Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway].(string)
|
||||||
|
|
||||||
|
if ipv4Gateway != "" {
|
||||||
|
cloudInitConfig.IPConfig[i].GatewayIPv4 = &ipv4Gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6 := configBlock[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6].([]interface{})
|
||||||
|
|
||||||
|
if len(ipv6) > 0 {
|
||||||
|
ipv6Block := ipv6[0].(map[string]interface{})
|
||||||
|
ipv6Address := ipv6Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address].(string)
|
||||||
|
|
||||||
|
if ipv6Address != "" {
|
||||||
|
cloudInitConfig.IPConfig[i].IPv6 = &ipv6Address
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6Gateway := ipv6Block[mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway].(string)
|
||||||
|
|
||||||
|
if ipv6Gateway != "" {
|
||||||
|
cloudInitConfig.IPConfig[i].GatewayIPv6 = &ipv6Gateway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudInitUserAccount := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccount].([]interface{})
|
||||||
|
|
||||||
|
if len(cloudInitUserAccount) > 0 {
|
||||||
|
cloudInitUserAccountBlock := cloudInitUserAccount[0].(map[string]interface{})
|
||||||
|
keys := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys].([]interface{})
|
||||||
|
|
||||||
|
if len(keys) > 0 {
|
||||||
|
sshKeys := make(proxmox.CustomCloudInitSSHKeys, len(keys))
|
||||||
|
|
||||||
|
for i, k := range keys {
|
||||||
|
sshKeys[i] = k.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudInitConfig.SSHKeys = &sshKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
password := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword].(string)
|
||||||
|
|
||||||
|
if password != "" {
|
||||||
|
cloudInitConfig.Password = &password
|
||||||
|
}
|
||||||
|
|
||||||
|
username := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername].(string)
|
||||||
|
|
||||||
|
cloudInitConfig.Username = &username
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudInitUserDataFileID := cloudInitBlock[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID].(string)
|
||||||
|
|
||||||
|
if cloudInitUserDataFileID != "" {
|
||||||
|
cloudInitConfig.Files = &proxmox.CustomCloudInitFiles{
|
||||||
|
UserVolume: &cloudInitUserDataFileID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cloudInitConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) error {
|
func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) error {
|
||||||
config := m.(providerConfiguration)
|
config := m.(providerConfiguration)
|
||||||
veClient, err := config.GetVEClient()
|
veClient, err := config.GetVEClient()
|
||||||
@ -1296,16 +1310,6 @@ func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) err
|
|||||||
cloudInit[mkResourceVirtualEnvironmentVMCloudInitDNS] = []interface{}{cloudInitDNS}
|
cloudInit[mkResourceVirtualEnvironmentVMCloudInitDNS] = []interface{}{cloudInitDNS}
|
||||||
}
|
}
|
||||||
|
|
||||||
if vmConfig.CloudInitFiles != nil {
|
|
||||||
if vmConfig.CloudInitFiles.UserVolume != nil {
|
|
||||||
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = *vmConfig.CloudInitFiles.UserVolume
|
|
||||||
} else {
|
|
||||||
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = dvResourceVirtualEnvironmentVMCloudInitUserDataFileID
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = dvResourceVirtualEnvironmentVMCloudInitUserDataFileID
|
|
||||||
}
|
|
||||||
|
|
||||||
ipConfigLast := -1
|
ipConfigLast := -1
|
||||||
ipConfigObjects := []*proxmox.CustomCloudInitIPConfig{
|
ipConfigObjects := []*proxmox.CustomCloudInitIPConfig{
|
||||||
vmConfig.IPConfig0,
|
vmConfig.IPConfig0,
|
||||||
@ -1398,6 +1402,16 @@ func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) err
|
|||||||
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserAccount] = []interface{}{cloudInitUserAccount}
|
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserAccount] = []interface{}{cloudInitUserAccount}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vmConfig.CloudInitFiles != nil {
|
||||||
|
if vmConfig.CloudInitFiles.UserVolume != nil {
|
||||||
|
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = *vmConfig.CloudInitFiles.UserVolume
|
||||||
|
} else {
|
||||||
|
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = dvResourceVirtualEnvironmentVMCloudInitUserDataFileID
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cloudInit[mkResourceVirtualEnvironmentVMCloudInitUserDataFileID] = dvResourceVirtualEnvironmentVMCloudInitUserDataFileID
|
||||||
|
}
|
||||||
|
|
||||||
if len(cloudInit) > 0 {
|
if len(cloudInit) > 0 {
|
||||||
d.Set(mkResourceVirtualEnvironmentVMCloudInit, []interface{}{cloudInit})
|
d.Set(mkResourceVirtualEnvironmentVMCloudInit, []interface{}{cloudInit})
|
||||||
} else {
|
} else {
|
||||||
@ -1677,7 +1691,7 @@ func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) err
|
|||||||
networkInterfaceNames := []interface{}{}
|
networkInterfaceNames := []interface{}{}
|
||||||
|
|
||||||
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
|
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
|
||||||
networkInterfaces, err := veClient.WaitForNetworkInterfacesFromAgent(nodeName, vmID, 600, 5)
|
networkInterfaces, err := veClient.WaitForNetworkInterfacesFromAgent(nodeName, vmID, 1800, 5)
|
||||||
|
|
||||||
if err == nil && networkInterfaces.Result != nil {
|
if err == nil && networkInterfaces.Result != nil {
|
||||||
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||||
@ -1723,14 +1737,116 @@ func resourceVirtualEnvironmentVMUpdate(d *schema.ResourceData, m interface{}) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string)
|
nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string)
|
||||||
|
rebootRequired := false
|
||||||
|
|
||||||
vmID, err := strconv.Atoi(d.Id())
|
vmID, err := strconv.Atoi(d.Id())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body := &proxmox.VirtualEnvironmentVMUpdateRequestBody{}
|
||||||
|
resource := resourceVirtualEnvironmentVM()
|
||||||
|
|
||||||
|
// Retrieve the entire configuration as we need to process certain values.
|
||||||
|
vmConfig, err := veClient.GetVM(nodeName, vmID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the new primitive configuration values.
|
||||||
|
description := d.Get(mkResourceVirtualEnvironmentVMDescription).(string)
|
||||||
|
name := d.Get(mkResourceVirtualEnvironmentVMName).(string)
|
||||||
|
osType := d.Get(mkResourceVirtualEnvironmentVMOSType).(string)
|
||||||
|
|
||||||
|
if description != "" {
|
||||||
|
body.Description = &description
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
body.Name = &name
|
||||||
|
}
|
||||||
|
|
||||||
|
body.OSType = &osType
|
||||||
|
|
||||||
|
// Prepare the new CPU configuration.
|
||||||
|
if d.HasChange(mkResourceVirtualEnvironmentVMCPU) {
|
||||||
|
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentVMCPU}, 0, true)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
||||||
|
cpuHotplugged := cpuBlock[mkResourceVirtualEnvironmentVMCPUHotplugged].(int)
|
||||||
|
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
||||||
|
|
||||||
|
if cpuCores > 0 {
|
||||||
|
body.CPUCores = &cpuCores
|
||||||
|
}
|
||||||
|
|
||||||
|
if cpuHotplugged > 0 {
|
||||||
|
body.VirtualCPUCount = &cpuHotplugged
|
||||||
|
}
|
||||||
|
|
||||||
|
if cpuSockets > 0 {
|
||||||
|
body.CPUSockets = &cpuSockets
|
||||||
|
}
|
||||||
|
|
||||||
|
rebootRequired = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the new cloud-init configuration.
|
||||||
|
if d.HasChange(mkResourceVirtualEnvironmentVMCloudInit) {
|
||||||
|
cloudInitConfig, err := resourceVirtualEnvironmentVMGetCloudConfig(d, m)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
body.CloudInitConfig = cloudInitConfig
|
||||||
|
|
||||||
|
rebootRequired = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the new memory configuration.
|
||||||
|
if d.HasChange(mkResourceVirtualEnvironmentVMMemory) {
|
||||||
|
memoryBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentVMMemory}, 0, true)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentVMMemoryDedicated].(int)
|
||||||
|
memoryFloating := memoryBlock[mkResourceVirtualEnvironmentVMMemoryFloating].(int)
|
||||||
|
memoryShared := memoryBlock[mkResourceVirtualEnvironmentVMMemoryShared].(int)
|
||||||
|
|
||||||
|
body.DedicatedMemory = &memoryDedicated
|
||||||
|
body.FloatingMemory = &memoryFloating
|
||||||
|
|
||||||
|
if memoryShared > 0 {
|
||||||
|
memorySharedName := fmt.Sprintf("vm-%d-ivshmem", vmID)
|
||||||
|
|
||||||
|
body.SharedMemory = &proxmox.CustomSharedMemory{
|
||||||
|
Name: &memorySharedName,
|
||||||
|
Size: memoryShared,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rebootRequired = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the configuration now that everything has been prepared.
|
||||||
|
err = veClient.UpdateVM(nodeName, vmID, body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Determine if the state of the virtual machine needs to be changed.
|
// Determine if the state of the virtual machine needs to be changed.
|
||||||
if d.HasChange(mkResourceVirtualEnvironmentVMStarted) {
|
if d.HasChange(mkResourceVirtualEnvironmentVMStarted) {
|
||||||
|
rebootRequired = false
|
||||||
started := d.Get(mkResourceVirtualEnvironmentVMStarted).(bool)
|
started := d.Get(mkResourceVirtualEnvironmentVMStarted).(bool)
|
||||||
|
|
||||||
if started {
|
if started {
|
||||||
@ -1766,6 +1882,28 @@ func resourceVirtualEnvironmentVMUpdate(d *schema.ResourceData, m interface{}) e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As a final step in the update procedure, we might need to reboot the virtual machine.
|
||||||
|
if rebootRequired {
|
||||||
|
rebootTimeout := 300
|
||||||
|
|
||||||
|
err = veClient.RebootVM(nodeName, vmID, &proxmox.VirtualEnvironmentVMRebootRequestBody{
|
||||||
|
Timeout: &rebootTimeout,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the agent to unpublish the network interfaces, if it's enabled.
|
||||||
|
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
|
||||||
|
err = veClient.WaitForNoNetworkInterfacesFromAgent(nodeName, vmID, 300, 5)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return resourceVirtualEnvironmentVMRead(d, m)
|
return resourceVirtualEnvironmentVMRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user