0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-08-25 12:55:41 +00:00

Initial work on container resource

This commit is contained in:
Dan Petersen 2020-01-02 07:57:48 +01:00
parent 0e4647f0ee
commit 6dac302a01
11 changed files with 2630 additions and 676 deletions

View File

@ -1,10 +1,16 @@
## 0.2.0 (UNRELEASED) ## 0.2.0 (UNRELEASED)
BREAKING CHANGES:
* resource/virtual_environment_vm: Rename `cloud_init` argument to `initialization`
* resource/virtual_environment_vm: Rename `os_type` argument to `os.type`
FEATURES: FEATURES:
* **New Data Source:** `proxmox_virtual_environment_dns` * **New Data Source:** `proxmox_virtual_environment_dns`
* **New Data Source:** `proxmox_virtual_environment_hosts` * **New Data Source:** `proxmox_virtual_environment_hosts`
* **New Resource:** `proxmox_virtual_environment_certificate` * **New Resource:** `proxmox_virtual_environment_certificate`
* **New Resource:** `proxmox_virtual_environment_container`
* **New Resource:** `proxmox_virtual_environment_dns` * **New Resource:** `proxmox_virtual_environment_dns`
* **New Resource:** `proxmox_virtual_environment_hosts` * **New Resource:** `proxmox_virtual_environment_hosts`
@ -12,7 +18,7 @@ ENHANCEMENTS:
* resource/virtual_environment_vm: Add `acpi` argument * resource/virtual_environment_vm: Add `acpi` argument
* resource/virtual_environment_vm: Add `bios` argument * resource/virtual_environment_vm: Add `bios` argument
* resource/virtual_environment_vm: Add `cpu.flags`, `cpu.type` and `cpu.units` arguments * resource/virtual_environment_vm: Add `cpu.architecture`, `cpu.flags`, `cpu.type` and `cpu.units` arguments
* resource/virtual_environment_vm: Add `tablet_device` argument * resource/virtual_environment_vm: Add `tablet_device` argument
* resource/virtual_environment_vm: Add `vga` argument * resource/virtual_environment_vm: Add `vga` argument

135
README.md
View File

@ -31,6 +31,7 @@ A Terraform Provider which adds support for Proxmox solutions.
- [Resources](#resources) - [Resources](#resources)
- [Virtual Environment](#virtual-environment-1) - [Virtual Environment](#virtual-environment-1)
- [Certificate](#certificate-proxmox_virtual_environment_certificate) - [Certificate](#certificate-proxmox_virtual_environment_certificate)
- [Container](#container-proxmox_virtual_environment_container)
- [DNS](#dns-proxmox_virtual_environment_dns-1) - [DNS](#dns-proxmox_virtual_environment_dns-1)
- [File](#file-proxmox_virtual_environment_file) - [File](#file-proxmox_virtual_environment_file)
- [Group](#group-proxmox_virtual_environment_group-1) - [Group](#group-proxmox_virtual_environment_group-1)
@ -38,7 +39,7 @@ A Terraform Provider which adds support for Proxmox solutions.
- [Pool](#pool-proxmox_virtual_environment_pool-1) - [Pool](#pool-proxmox_virtual_environment_pool-1)
- [Role](#role-proxmox_virtual_environment_role-1) - [Role](#role-proxmox_virtual_environment_role-1)
- [User](#user-proxmox_virtual_environment_user-1) - [User](#user-proxmox_virtual_environment_user-1)
- [VM](#vm-proxmox_virtual_environment_vm) - [Virtual Machine](#virtual-machine-proxmox_virtual_environment_vm)
- [Developing the Provider](#developing-the-provider) - [Developing the Provider](#developing-the-provider)
- [Testing the Provider](#testing-the-provider) - [Testing the Provider](#testing-the-provider)
- [Known issues](#known-issues) - [Known issues](#known-issues)
@ -284,6 +285,70 @@ This data source doesn't accept arguments.
* `subject` - The subject * `subject` - The subject
* `subject_alternative_names` - The subject alternative names * `subject_alternative_names` - The subject alternative names
##### Container (proxmox_virtual_environment_container)
###### Arguments
* `console` - (Optional) The console configuration
* `enabled` - (Optional) Whether to enable the console device (defaults to `true`)
* `mode` - (Optional) The console mode (defaults to `tty`)
* `console` - Console
* `shell` - Shell
* `tty` - TTY
* `tty_count` - (Optional) The number of available TTY (defaults to `2`)
* `cpu` - (Optional) The CPU configuration
* `architecture` - (Optional) The CPU architecture (defaults to `amd64`)
* `amd64` - x86 (64 bit)
* `arm64` - ARM (64-bit)
* `armhf` - ARM (32 bit)
* `i386` - x86 (32 bit)
* `cores` - (Optional) The number of CPU cores (defaults to `1`)
* `units` - (Optional) The CPU units (defaults to `1024`)
* `description` - (Optional) The description
* `initialization` - (Optional) The initialization configuration
* `dns` - (Optional) The DNS configuration
* `domain` - (Optional) The DNS search domain
* `server` - (Optional) The DNS server
* `hostname` - (Optional) The hostname
* `ip_config` - (Optional) The IP configuration (one block per network device)
* `ipv4` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv4 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv4 gateway (must be omitted when `dhcp` is used as the address)
* `ipv6` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv6 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv6 gateway (must be omitted when `dhcp` is used as the address)
* `user_account` - (Optional) The user account configuration
* `keys` - (Optional) The SSH keys for the root account
* `password` - (Optional) The password for the root account
* `memory` - (Optional) The memory configuration
* `dedicated` - (Optional) The dedicated memory in megabytes (defaults to `512`)
* `swap` - (Optional) The swap size in megabytes (defaults to `0`)
* `network_interface` - (Optional) A network interface (multiple blocks supported)
* `bridge` - (Optional) The name of the network bridge (defaults to `vmbr0`)
* `enabled` - (Optional) Whether to enable the network device (defaults to `true`)
* `mac_address` - (Optional) The MAC address
* `name` - (Required) The network interface name
* `rate_limit` - (Optional) The rate limit in megabytes per second
* `vlan_id` - (Optional) The VLAN identifier
* `node_name` - (Required) The name of the node to assign the container to
* `operating_system` - (Required) The Operating System configuration
* `template_file_id` - (Required) The ID of an OS template file
* `type` - (Optional) The type (defaults to `unmanaged`)
* `alpine` - Alpine
* `archlinux` - Arch Linux
* `centos` - CentOS
* `debian` - Debian
* `fedora` - Fedora
* `gentoo` - Gentoo
* `opensuse` - openSUSE
* `ubuntu` - Ubuntu
* `unmanaged` - Unmanaged
* `pool_id` - (Optional) The ID of a pool to assign the container to
* `started` - (Optional) Whether to start the container (defaults to `true`)
* `vm_id` - (Optional) The ID
###### Attributes
This resource doesn't expose any additional attributes.
##### DNS (proxmox_virtual_environment_dns) ##### DNS (proxmox_virtual_environment_dns)
###### Arguments ###### Arguments
@ -400,7 +465,7 @@ This resource doesn't expose any additional attributes.
###### Attributes ###### Attributes
This resource doesn't expose any additional attributes. This resource doesn't expose any additional attributes.
##### VM (proxmox_virtual_environment_vm) ##### Virtual Machine (proxmox_virtual_environment_vm)
###### Arguments ###### Arguments
* `acpi` - (Optional) Whether to enable ACPI (defaults to `true`) * `acpi` - (Optional) Whether to enable ACPI (defaults to `true`)
@ -416,23 +481,10 @@ This resource doesn't expose any additional attributes.
* `cdrom` - (Optional) The CDROM configuration * `cdrom` - (Optional) The CDROM configuration
* `enabled` - (Optional) Whether to enable the CDROM drive (defaults to `false`) * `enabled` - (Optional) Whether to enable the CDROM drive (defaults to `false`)
* `file_id` - (Optional) A file ID for an ISO file (defaults to `cdrom` as in the physical drive) * `file_id` - (Optional) A file ID for an ISO file (defaults to `cdrom` as in the physical drive)
* `cloud_init` - (Optional) The cloud-init configuration (conflicts with `cdrom`)
* `dns` - (Optional) The DNS configuration
* `domain` - (Optional) The DNS search domain
* `server` - (Optional) The DNS server
* `ip_config` - (Optional) The IP configuration (one block per network device)
* `ipv4` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv4 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv4 gateway (must be omitted when `dhcp` is used as the address)
* `ipv6` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv6 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv6 gateway (must be omitted when `dhcp` is used as the address)
* `user_account` - (Required) The user account configuration (conflicts with `user_data_file_id`)
* `keys` - (Required) The SSH keys
* `password` - (Optional) The SSH password
* `username` - (Required) The SSH username
* `user_data_file_id` - (Optional) The ID of a file containing custom user data (conflicts with `user_account`)
* `cpu` - (Optional) The CPU configuration * `cpu` - (Optional) The CPU configuration
* `architecture` - (Optional) The CPU architecture (defaults to `x86_64`)
* `aarch64` - ARM (64 bit)
* `x86_64` - x86 (64-bit)
* `cores` - (Optional) The number of CPU cores (defaults to `1`) * `cores` - (Optional) The number of CPU cores (defaults to `1`)
* `flags` - (Optional) The CPU flags * `flags` - (Optional) The CPU flags
* `+aes`/`-aes` - Activate AES instruction set for HW acceleration * `+aes`/`-aes` - Activate AES instruction set for HW acceleration
@ -482,7 +534,7 @@ This resource doesn't expose any additional attributes.
* `qemu32`/`qemu64` - QEMU Virtual CPU version 2.5+ (32 & 64 bit variants) * `qemu32`/`qemu64` - QEMU Virtual CPU version 2.5+ (32 & 64 bit variants)
* `units` - (Optional) The CPU units (defaults to `1024`) * `units` - (Optional) The CPU units (defaults to `1024`)
* `description` - (Optional) The description * `description` - (Optional) The description
* `disk` - (Optional) The disk configuration (multiple blocks supported) * `disk` - (Optional) A disk (multiple blocks supported)
* `datastore_id` - (Optional) The ID of the datastore to create the disk in (defaults to `local-lvm`) * `datastore_id` - (Optional) The ID of the datastore to create the disk in (defaults to `local-lvm`)
* `file_format` - (Optional) The file format (defaults to `qcow2`) * `file_format` - (Optional) The file format (defaults to `qcow2`)
* `qcow2` - QEMU Disk Image v2 * `qcow2` - QEMU Disk Image v2
@ -495,6 +547,22 @@ This resource doesn't expose any additional attributes.
* `read_burstable` - (Optional) The maximum burstable read speed in megabytes per second * `read_burstable` - (Optional) The maximum burstable read speed in megabytes per second
* `write` - (Optional) The maximum write speed in megabytes per second * `write` - (Optional) The maximum write speed in megabytes per second
* `write_burstable` - (Optional) The maximum burstable write speed in megabytes per second * `write_burstable` - (Optional) The maximum burstable write speed in megabytes per second
* `initialization` - (Optional) The cloud-init configuration (conflicts with `cdrom`)
* `dns` - (Optional) The DNS configuration
* `domain` - (Optional) The DNS search domain
* `server` - (Optional) The DNS server
* `ip_config` - (Optional) The IP configuration (one block per network device)
* `ipv4` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv4 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv4 gateway (must be omitted when `dhcp` is used as the address)
* `ipv6` - (Optional) The IPv4 configuration
* `address` - (Optional) The IPv6 address (use `dhcp` for autodiscovery)
* `gateway` - (Optional) The IPv6 gateway (must be omitted when `dhcp` is used as the address)
* `user_account` - (Optional) The user account configuration (conflicts with `user_data_file_id`)
* `keys` - (Optional) The SSH keys
* `password` - (Optional) The SSH password
* `username` - (Optional) The SSH username
* `user_data_file_id` - (Optional) The ID of a file containing custom user data (conflicts with `user_account`)
* `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`) * `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`)
* `da` - Danish * `da` - Danish
* `de` - German * `de` - German
@ -526,7 +594,7 @@ This resource doesn't expose any additional attributes.
* `floating` - (Optional) The floating memory in megabytes (defaults to `0`) * `floating` - (Optional) The floating memory in megabytes (defaults to `0`)
* `shared` - (Optional) The shared memory in megabytes (defaults to `0`) * `shared` - (Optional) The shared memory in megabytes (defaults to `0`)
* `name` - (Optional) The name * `name` - (Optional) The name
* `network_device` - (Optional) The network device configuration (multiple blocks supported) * `network_device` - (Optional) A network device (multiple blocks supported)
* `bridge` - (Optional) The name of the network bridge (defaults to `vmbr0`) * `bridge` - (Optional) The name of the network bridge (defaults to `vmbr0`)
* `enabled` - (Optional) Whether to enable the network device (defaults to `true`) * `enabled` - (Optional) Whether to enable the network device (defaults to `true`)
* `mac_address` - (Optional) The MAC address * `mac_address` - (Optional) The MAC address
@ -538,19 +606,20 @@ This resource doesn't expose any additional attributes.
* `rate_limit` - (Optional) The rate limit in megabytes per second * `rate_limit` - (Optional) The rate limit in megabytes per second
* `vlan_id` - (Optional) The VLAN identifier * `vlan_id` - (Optional) The VLAN identifier
* `node_name` - (Required) The name of the node to assign the virtual machine to * `node_name` - (Required) The name of the node to assign the virtual machine to
* `os_type` - (Optional) The OS type (defaults to `other`) * `operating_system` - (Required) The Operating System configuration
* `l24` - Linux Kernel 2.4 * `type` - (Optional) The type (defaults to `other`)
* `l26` - Linux Kernel 2.6 - 5.X * `l24` - Linux Kernel 2.4
* `other` - Unspecified OS * `l26` - Linux Kernel 2.6 - 5.X
* `solaris` - OpenIndiania, OpenSolaris og Solaris Kernel * `other` - Unspecified OS
* `w2k` - Windows 2000 * `solaris` - OpenIndiania, OpenSolaris og Solaris Kernel
* `w2k3` - Windows 2003 * `w2k` - Windows 2000
* `w2k8` - Windows 2008 * `w2k3` - Windows 2003
* `win7` - Windows 7 * `w2k8` - Windows 2008
* `win8` - Windows 8, 2012 or 2012 R2 * `win7` - Windows 7
* `win10` - Windows 10 or 2016 * `win8` - Windows 8, 2012 or 2012 R2
* `wvista` - Windows Vista * `win10` - Windows 10 or 2016
* `wxp` - Windows XP * `wvista` - Windows Vista
* `wxp` - Windows XP
* `pool_id` - (Optional) The ID of a pool to assign the virtual machine to * `pool_id` - (Optional) The ID of a pool to assign the virtual machine to
* `started` - (Optional) Whether to start the virtual machine (defaults to `true`) * `started` - (Optional) Whether to start the virtual machine (defaults to `true`)
* `tablet_device` - (Optional) Whether to enable the USB tablet device (defaults to `true`) * `tablet_device` - (Optional) Whether to enable the USB tablet device (defaults to `true`)

View File

@ -3,7 +3,14 @@ resource "proxmox_virtual_environment_vm" "example" {
enabled = true enabled = true
} }
cloud_init { description = "Managed by Terraform"
disk {
datastore_id = "${element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local-lvm"))}"
file_id = "${proxmox_virtual_environment_file.ubuntu_cloud_image.id}"
}
initialization {
dns { dns {
server = "1.1.1.1" server = "1.1.1.1"
} }
@ -23,21 +30,18 @@ resource "proxmox_virtual_environment_vm" "example" {
user_data_file_id = "${proxmox_virtual_environment_file.cloud_config.id}" user_data_file_id = "${proxmox_virtual_environment_file.cloud_config.id}"
} }
description = "Managed by Terraform"
disk {
datastore_id = "${element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local-lvm"))}"
file_id = "${proxmox_virtual_environment_file.ubuntu_cloud_image.id}"
}
name = "terraform-provider-proxmox-example" name = "terraform-provider-proxmox-example"
network_device {} network_device {}
node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}" node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}"
os_type = "l26"
pool_id = "${proxmox_virtual_environment_pool.example.id}" operating_system {
vm_id = 2038 type = "l26"
}
pool_id = "${proxmox_virtual_environment_pool.example.id}"
vm_id = 2038
connection { connection {
type = "ssh" type = "ssh"

View File

@ -0,0 +1,112 @@
/* 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 proxmox
import (
"errors"
"fmt"
"net/url"
"strings"
"time"
)
// CreateContainer creates a container.
func (c *VirtualEnvironmentClient) CreateContainer(nodeName string, d *VirtualEnvironmentContainerCreateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
}
// DeleteContainer deletes a container.
func (c *VirtualEnvironmentClient) DeleteContainer(nodeName string, vmID int) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID), nil, nil)
}
// GetContainer retrieves a container.
func (c *VirtualEnvironmentClient) GetContainer(nodeName string, vmID int) (*VirtualEnvironmentContainerGetResponseData, error) {
resBody := &VirtualEnvironmentContainerGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
}
return resBody.Data, nil
}
// GetContainerStatus retrieves the status for a container.
func (c *VirtualEnvironmentClient) GetContainerStatus(nodeName string, vmID int) (*VirtualEnvironmentContainerGetStatusResponseData, error) {
resBody := &VirtualEnvironmentContainerGetStatusResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/lxc/%d/status/current", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
}
return resBody.Data, nil
}
// RebootContainer reboots a container.
func (c *VirtualEnvironmentClient) RebootContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerRebootRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/reboot", url.PathEscape(nodeName), vmID), d, nil)
}
// ShutdownContainer shuts down a container.
func (c *VirtualEnvironmentClient) ShutdownContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerShutdownRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil)
}
// StartContainer starts a container.
func (c *VirtualEnvironmentClient) StartContainer(nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID), nil, nil)
}
// StopContainer stops a container immediately.
func (c *VirtualEnvironmentClient) StopContainer(nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID), nil, nil)
}
// UpdateContainer updates a container.
func (c *VirtualEnvironmentClient) UpdateContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), d, nil)
}
// WaitForContainerState waits for a container to reach a specific state.
func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID int, state string, timeout int, delay int) error {
state = strings.ToLower(state)
timeDelay := int64(delay)
timeMax := float64(timeout)
timeStart := time.Now()
timeElapsed := timeStart.Sub(timeStart)
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetContainerStatus(nodeName, vmID)
if err != nil {
return err
}
if data.Status == state {
return nil
}
time.Sleep(1 * time.Second)
}
time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart)
}
return fmt.Errorf("Timeout while waiting for container \"%d\" to enter the state \"%s\"", vmID, state)
}

View File

@ -0,0 +1,777 @@
/* 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 proxmox
import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
)
// VirtualEnvironmentContainerCreateRequestBody contains the data for an user create request.
type VirtualEnvironmentContainerCreateRequestBody struct {
BandwidthLimit *float64 `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
ConsoleEnabled *CustomBool `json:"console,omitempty" url:"console,omitempty,int"`
ConsoleMode *string `json:"cmode,omitempty" url:"cmode,omitempty"`
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
DatastoreID *string `json:"storage,omitempty" url:"storage,omitempty"`
DedicatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
DNSDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
DNSServer *string `json:"nameserver,omitempty" url:"nameserver,omitempty"`
Features *VirtualEnvironmentContainerCustomFeatures `json:"features,omitempty" url:"features,omitempty"`
Force *CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
IgnoreUnpackErrors *CustomBool `json:"ignore-unpack-errors,omitempty" url:"force,omitempty,int"`
Lock *string `json:"lock,omitempty" url:"lock,omitempty,int"`
MountPoints VirtualEnvironmentContainerCustomMountPointArray `json:"mp,omitempty" url:"mp,omitempty,numbered"`
NetworkInterfaces VirtualEnvironmentContainerCustomNetworkInterfaceArray `json:"net,omitempty" url:"net,omitempty,numbered"`
OSTemplateFileVolume string `json:"ostemplate" url:"ostemplate"`
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
Password *string `json:"password,omitempty" url:"password,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Protection *CustomBool `json:"protection,omitempty" url:"protection,omitempty,int"`
Restore *CustomBool `json:"restore,omitempty" url:"restore,omitempty,int"`
RootFS *VirtualEnvironmentContainerCustomRootFS `json:"rootfs,omitempty" url:"rootfs,omitempty"`
SSHKeys *VirtualEnvironmentContainerCustomSSHKeys `json:"ssh-public-keys,omitempty" url:"ssh-public-keys,omitempty"`
Start *CustomBool `json:"start,omitempty" url:"start,omitempty,int"`
StartOnBoot *CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
StartupBehavior *VirtualEnvironmentContainerCustomStartupBehavior `json:"startup,omitempty" url:"startup,omitempty"`
Swap *int `json:"swap,omitempty" url:"swap,omitempty"`
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
TTY *int `json:"tty,omitempty" url:"tty,omitempty"`
Unique *CustomBool `json:"unique,omitempty" url:"unique,omitempty,int"`
Unprivileged *CustomBool `json:"unprivileged,omitempty" url:"unprivileged,omitempty,int"`
VMID int `json:"vmid" url:"vmid"`
}
// VirtualEnvironmentContainerCustomFeatures contains the values for the "features" property.
type VirtualEnvironmentContainerCustomFeatures struct {
FUSE *CustomBool `json:"fuse,omitempty" url:"fuse,omitempty,int"`
KeyControl *CustomBool `json:"keyctl,omitempty" url:"keyctl,omitempty,int"`
MountTypes *[]string `json:"mount,omitempty" url:"mount,omitempty"`
Nesting *CustomBool `json:"nesting,omitempty" url:"nesting,omitempty,int"`
}
// VirtualEnvironmentContainerCustomMountPoint contains the values for the "mp[n]" properties.
type VirtualEnvironmentContainerCustomMountPoint struct {
ACL *CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
Backup *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
DiskSize *int `json:"size,omitempty" url:"size,omitempty"`
Enabled bool `json:"-" url:"-"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
MountPoint string `json:"mp" url:"mp"`
Quota *CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
}
// VirtualEnvironmentContainerCustomMountPointArray is an array of VirtualEnvironmentContainerCustomMountPoint.
type VirtualEnvironmentContainerCustomMountPointArray []VirtualEnvironmentContainerCustomMountPoint
// VirtualEnvironmentContainerCustomNetworkInterface contains the values for the "net[n]" properties.
type VirtualEnvironmentContainerCustomNetworkInterface struct {
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
Enabled bool `json:"-" url:"-"`
Firewall *CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
IPv4Address *string `json:"ip,omitempty" url:"ip,omitempty"`
IPv4Gateway *string `json:"gw,omitempty" url:"gw,omitempty"`
IPv6Address *string `json:"ip6,omitempty" url:"ip6,omitempty"`
IPv6Gateway *string `json:"gw6,omitempty" url:"gw6,omitempty"`
MACAddress *string `json:"hwaddr,omitempty" url:"hwaddr,omitempty"`
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
Name string `json:"name" url:"name"`
RateLimit *int `json:"rate,omitempty" url:"rate,omitempty"`
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
Trunks *[]int `json:"trunks,omitempty" url:"trunks,omitempty"`
Type *string `json:"type,omitempty" url:"type,omitempty"`
}
// VirtualEnvironmentContainerCustomNetworkInterfaceArray is an array of VirtualEnvironmentContainerCustomNetworkInterface.
type VirtualEnvironmentContainerCustomNetworkInterfaceArray []VirtualEnvironmentContainerCustomNetworkInterface
// VirtualEnvironmentContainerCustomRootFS contains the values for the "rootfs" property.
type VirtualEnvironmentContainerCustomRootFS struct {
ACL *CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
DiskSize *int `json:"size,omitempty" url:"size,omitempty"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
Quota *CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
}
// VirtualEnvironmentContainerCustomSSHKeys contains the values for the "ssh-public-keys" property.
type VirtualEnvironmentContainerCustomSSHKeys []string
// VirtualEnvironmentContainerCustomStartupBehavior contains the values for the "startup" property.
type VirtualEnvironmentContainerCustomStartupBehavior struct {
Down *int `json:"down,omitempty" url:"down,omitempty"`
Order *int `json:"order,omitempty" url:"order,omitempty"`
Up *int `json:"up,omitempty" url:"up,omitempty"`
}
// VirtualEnvironmentContainerGetResponseBody contains the body from an user get response.
type VirtualEnvironmentContainerGetResponseBody struct {
Data *VirtualEnvironmentContainerGetResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentContainerGetResponseData contains the data from an user get response.
type VirtualEnvironmentContainerGetResponseData struct {
ConsoleEnabled *CustomBool `json:"console,omitempty"`
ConsoleMode *string `json:"cmode,omitempty"`
CPUArchitecture *string `json:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty"`
CPULimit *int `json:"cpulimit,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty"`
DedicatedMemory *int `json:"memory,omitempty"`
Description *string `json:"description,omitempty"`
Digest string `json:"digest"`
DNSDomain *string `json:"searchdomain,omitempty"`
DNSServer *string `json:"nameserver,omitempty"`
Features *VirtualEnvironmentContainerCustomFeatures `json:"features,omitempty"`
HookScript *string `json:"hookscript,omitempty"`
Hostname *string `json:"hostname,omitempty"`
Lock *CustomBool `json:"lock,omitempty"`
LXCConfiguration *[]string `json:"lxc,omitempty"`
MountPoint0 VirtualEnvironmentContainerCustomMountPointArray `json:"mp0,omitempty"`
MountPoint1 VirtualEnvironmentContainerCustomMountPointArray `json:"mp1,omitempty"`
MountPoint2 VirtualEnvironmentContainerCustomMountPointArray `json:"mp2,omitempty"`
MountPoint3 VirtualEnvironmentContainerCustomMountPointArray `json:"mp3,omitempty"`
NetworkInterface0 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net0,omitempty"`
NetworkInterface1 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net1,omitempty"`
NetworkInterface2 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net2,omitempty"`
NetworkInterface3 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net3,omitempty"`
NetworkInterface4 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net4,omitempty"`
NetworkInterface5 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net5,omitempty"`
NetworkInterface6 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net6,omitempty"`
NetworkInterface7 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net7,omitempty"`
OSType *string `json:"ostype,omitempty"`
Protection *CustomBool `json:"protection,omitempty"`
RootFS *VirtualEnvironmentContainerCustomRootFS `json:"rootfs,omitempty"`
StartOnBoot *CustomBool `json:"onboot,omitempty"`
StartupBehavior *VirtualEnvironmentContainerCustomStartupBehavior `json:"startup,omitempty"`
Swap *int `json:"swap,omitempty"`
Tags *string `json:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty"`
TTY *int `json:"tty,omitempty"`
Unprivileged *CustomBool `json:"unprivileged,omitempty"`
}
// VirtualEnvironmentContainerGetStatusResponseBody contains the body from a container get status response.
type VirtualEnvironmentContainerGetStatusResponseBody struct {
Data *VirtualEnvironmentContainerGetStatusResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentContainerGetStatusResponseData contains the data from a container get status response.
type VirtualEnvironmentContainerGetStatusResponseData struct {
CPUCount *float64 `json:"cpus,omitempty"`
Lock *string `json:"lock,omitempty"`
MemoryAllocation *int `json:"maxmem,omitempty"`
Name *string `json:"name,omitempty"`
RootDiskSize *int `json:"maxdisk,omitempty"`
Status string `json:"status,omitempty"`
SwapAllocation *int `json:"maxswap,omitempty"`
Tags *string `json:"tags,omitempty"`
Uptime *int `json:"uptime,omitempty"`
VMID string `json:"vmid,omitempty"`
}
// VirtualEnvironmentContainerRebootRequestBody contains the body for a container reboot request.
type VirtualEnvironmentContainerRebootRequestBody struct {
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
}
// VirtualEnvironmentContainerShutdownRequestBody contains the body for a container shutdown request.
type VirtualEnvironmentContainerShutdownRequestBody struct {
ForceStop *CustomBool `json:"forceStop,omitempty,int" url:"forceStop,omitempty,int"`
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
}
// VirtualEnvironmentContainerUpdateRequestBody contains the data for an user update request.
type VirtualEnvironmentContainerUpdateRequestBody VirtualEnvironmentContainerCreateRequestBody
// EncodeValues converts a VirtualEnvironmentContainerCustomFeatures struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *url.Values) error {
values := []string{}
if r.FUSE != nil {
if *r.FUSE {
values = append(values, "fuse=1")
} else {
values = append(values, "fuse=0")
}
}
if r.KeyControl != nil {
if *r.KeyControl {
values = append(values, "keyctl=1")
} else {
values = append(values, "keyctl=0")
}
}
if r.MountTypes != nil {
if len(*r.MountTypes) > 0 {
values = append(values, fmt.Sprintf("mount=%s", strings.Join(*r.MountTypes, ";")))
}
}
if r.Nesting != nil {
if *r.Nesting {
values = append(values, "nesting=1")
} else {
values = append(values, "nesting=0")
}
}
if len(values) > 0 {
v.Add(key, strings.Join(values, ","))
}
return nil
}
// EncodeValues converts a VirtualEnvironmentContainerCustomMountPoint struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v *url.Values) error {
values := []string{}
if r.ACL != nil {
if *r.ACL {
values = append(values, "acl=%d")
} else {
values = append(values, "acl=0")
}
}
if r.Backup != nil {
if *r.Backup {
values = append(values, "backup=1")
} else {
values = append(values, "backup=0")
}
}
if r.DiskSize != nil {
values = append(values, fmt.Sprintf("size=%d", *r.DiskSize))
}
if r.MountOptions != nil {
if len(*r.MountOptions) > 0 {
values = append(values, fmt.Sprintf("mount=%s", strings.Join(*r.MountOptions, ";")))
}
}
values = append(values, fmt.Sprintf("mp=%s", r.MountPoint))
if r.Quota != nil {
if *r.Quota {
values = append(values, "quota=1")
} else {
values = append(values, "quota=0")
}
}
if r.ReadOnly != nil {
if *r.ReadOnly {
values = append(values, "ro=1")
} else {
values = append(values, "ro=0")
}
}
if r.Replicate != nil {
if *r.ReadOnly {
values = append(values, "replicate=1")
} else {
values = append(values, "replicate=0")
}
}
if r.Shared != nil {
if *r.Shared {
values = append(values, "shared=1")
} else {
values = append(values, "shared=0")
}
}
values = append(values, fmt.Sprintf("volume=%s", r.Volume))
if len(values) > 0 {
v.Add(key, strings.Join(values, ","))
}
return nil
}
// EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterface struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomNetworkInterface) EncodeValues(key string, v *url.Values) error {
values := []string{}
if r.Bridge != nil {
values = append(values, fmt.Sprintf("bridge=%s", *r.Bridge))
}
if r.Firewall != nil {
if *r.Firewall {
values = append(values, "firewall=1")
} else {
values = append(values, "firewall=0")
}
}
if r.IPv4Address != nil {
values = append(values, fmt.Sprintf("ip=%s", *r.IPv4Address))
}
if r.IPv4Gateway != nil {
values = append(values, fmt.Sprintf("gw=%s", *r.IPv4Gateway))
}
if r.IPv6Address != nil {
values = append(values, fmt.Sprintf("ip6=%s", *r.IPv6Address))
}
if r.IPv6Gateway != nil {
values = append(values, fmt.Sprintf("gw6=%s", *r.IPv6Gateway))
}
if r.MACAddress != nil {
values = append(values, fmt.Sprintf("hwaddr=%s", *r.MACAddress))
}
if r.MTU != nil {
values = append(values, fmt.Sprintf("mtu=%d", *r.MTU))
}
values = append(values, fmt.Sprintf("name=%s", r.Name))
if r.RateLimit != nil {
values = append(values, fmt.Sprintf("rate=%d", *r.RateLimit))
}
if r.Tag != nil {
values = append(values, fmt.Sprintf("tag=%d", *r.Tag))
}
if r.Trunks != nil && len(*r.Trunks) > 0 {
sTrunks := make([]string, len(*r.Trunks))
for i, v := range *r.Trunks {
sTrunks[i] = strconv.Itoa(v)
}
values = append(values, fmt.Sprintf("trunks=%s", strings.Join(sTrunks, ";")))
}
if r.Type != nil {
values = append(values, fmt.Sprintf("type=%s", *r.Type))
}
if len(values) > 0 {
v.Add(key, strings.Join(values, ","))
}
return nil
}
// EncodeValues converts a VirtualEnvironmentContainerCustomRootFS struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomRootFS) EncodeValues(key string, v *url.Values) error {
values := []string{}
if r.ACL != nil {
if *r.ACL {
values = append(values, "acl=%d")
} else {
values = append(values, "acl=0")
}
}
if r.DiskSize != nil {
values = append(values, fmt.Sprintf("size=%d", *r.DiskSize))
}
if r.MountOptions != nil {
if len(*r.MountOptions) > 0 {
values = append(values, fmt.Sprintf("mount=%s", strings.Join(*r.MountOptions, ";")))
}
}
if r.Quota != nil {
if *r.Quota {
values = append(values, "quota=1")
} else {
values = append(values, "quota=0")
}
}
if r.ReadOnly != nil {
if *r.ReadOnly {
values = append(values, "ro=1")
} else {
values = append(values, "ro=0")
}
}
if r.Replicate != nil {
if *r.ReadOnly {
values = append(values, "replicate=1")
} else {
values = append(values, "replicate=0")
}
}
if r.Shared != nil {
if *r.Shared {
values = append(values, "shared=1")
} else {
values = append(values, "shared=0")
}
}
values = append(values, fmt.Sprintf("volume=%s", r.Volume))
if len(values) > 0 {
v.Add(key, strings.Join(values, ","))
}
return nil
}
// EncodeValues converts a VirtualEnvironmentContainerCustomSSHKeys array to a URL vlaue.
func (r VirtualEnvironmentContainerCustomSSHKeys) EncodeValues(key string, v *url.Values) error {
v.Add(key, strings.ReplaceAll(url.QueryEscape(strings.Join(r, "\n")), "+", "%20"))
return nil
}
// EncodeValues converts a VirtualEnvironmentContainerCustomStartupBehavior struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomStartupBehavior) EncodeValues(key string, v *url.Values) error {
values := []string{}
if r.Down != nil {
values = append(values, fmt.Sprintf("down=%d", *r.Down))
}
if r.Order != nil {
values = append(values, fmt.Sprintf("order=%d", *r.Order))
}
if r.Up != nil {
values = append(values, fmt.Sprintf("up=%d", *r.Up))
}
if len(values) > 0 {
v.Add(key, strings.Join(values, ","))
}
return nil
}
// UnmarshalJSON converts a VirtualEnvironmentContainerCustomFeatures string to an object.
func (r *VirtualEnvironmentContainerCustomFeatures) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 2 {
switch v[0] {
case "fuse":
bv := CustomBool(v[1] == "1")
r.FUSE = &bv
case "keyctl":
bv := CustomBool(v[1] == "1")
r.KeyControl = &bv
case "mount":
if v[1] != "" {
a := strings.Split(v[1], ";")
r.MountTypes = &a
} else {
a := []string{}
r.MountTypes = &a
}
case "nesting":
bv := CustomBool(v[1] == "1")
r.Nesting = &bv
}
}
}
return nil
}
// UnmarshalJSON converts a VirtualEnvironmentContainerCustomMountPoint string to an object.
func (r *VirtualEnvironmentContainerCustomMountPoint) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
r.Volume = v[1]
} else if len(v) == 2 {
switch v[0] {
case "acl":
bv := CustomBool(v[1] == "1")
r.ACL = &bv
case "backup":
bv := CustomBool(v[1] == "1")
r.Backup = &bv
case "mountoptions":
if v[1] != "" {
a := strings.Split(v[1], ";")
r.MountOptions = &a
} else {
a := []string{}
r.MountOptions = &a
}
case "mp":
r.MountPoint = v[1]
case "quota":
bv := CustomBool(v[1] == "1")
r.Quota = &bv
case "ro":
bv := CustomBool(v[1] == "1")
r.ReadOnly = &bv
case "replicate":
bv := CustomBool(v[1] == "1")
r.Replicate = &bv
case "shared":
bv := CustomBool(v[1] == "1")
r.Shared = &bv
case "size":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.DiskSize = &iv
}
}
}
return nil
}
// UnmarshalJSON converts a VirtualEnvironmentContainerCustomNetworkInterface string to an object.
func (r *VirtualEnvironmentContainerCustomNetworkInterface) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
r.Name = v[1]
} else if len(v) == 2 {
switch v[0] {
case "bridge":
r.Bridge = &v[1]
case "firewall":
bv := CustomBool(v[1] == "1")
r.Firewall = &bv
case "gw":
r.IPv4Gateway = &v[1]
case "gw6":
r.IPv6Gateway = &v[1]
case "ip":
r.IPv4Address = &v[1]
case "ip6":
r.IPv6Address = &v[1]
case "hwaddr":
r.MACAddress = &v[1]
case "mtu":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.MTU = &iv
case "name":
r.Name = v[1]
case "rate":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.RateLimit = &iv
case "tag":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.Tag = &iv
case "trunks":
if v[1] != "" {
trunks := strings.Split(v[1], ";")
a := make([]int, len(trunks))
for ti, tv := range trunks {
a[ti], err = strconv.Atoi(tv)
if err != nil {
return err
}
}
r.Trunks = &a
} else {
a := []int{}
r.Trunks = &a
}
case "type":
r.Type = &v[1]
}
}
}
return nil
}
// UnmarshalJSON converts a VirtualEnvironmentContainerCustomRootFS string to an object.
func (r *VirtualEnvironmentContainerCustomRootFS) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
r.Volume = v[1]
} else if len(v) == 2 {
switch v[0] {
case "acl":
bv := CustomBool(v[1] == "1")
r.ACL = &bv
case "mountoptions":
if v[1] != "" {
a := strings.Split(v[1], ";")
r.MountOptions = &a
} else {
a := []string{}
r.MountOptions = &a
}
case "quota":
bv := CustomBool(v[1] == "1")
r.Quota = &bv
case "ro":
bv := CustomBool(v[1] == "1")
r.ReadOnly = &bv
case "replicate":
bv := CustomBool(v[1] == "1")
r.Replicate = &bv
case "shared":
bv := CustomBool(v[1] == "1")
r.Shared = &bv
case "size":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.DiskSize = &iv
}
}
}
return nil
}
// UnmarshalJSON converts a VirtualEnvironmentContainerCustomStartupBehavior string to an object.
func (r *VirtualEnvironmentContainerCustomStartupBehavior) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 2 {
switch v[0] {
case "down":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.Down = &iv
case "order":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.Order = &iv
case "up":
iv, err := strconv.Atoi(v[1])
if err != nil {
return err
}
r.Up = &iv
}
}
}
return nil
}

View File

@ -133,8 +133,8 @@ func (c *VirtualEnvironmentClient) UpdateVMAsync(nodeName string, vmID int, d *V
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil)
} }
// WaitForNetworkInterfacesFromAgent waits for a virtual machine's QEMU agent to publish the network interfaces. // WaitForNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to publish the network interfaces.
func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromAgent(nodeName string, vmID int, timeout int, delay int) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) { func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -159,8 +159,8 @@ 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. // WaitForNoNetworkInterfacesFromVMAgent 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 { func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int) error {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -185,8 +185,8 @@ func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromAgent(nodeName
return fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to unpublish the network interfaces", vmID) 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. // WaitForVMState 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) WaitForVMState(nodeName string, vmID int, state string, timeout int, delay int) error {
state = strings.ToLower(state) state = strings.ToLower(state)
timeDelay := int64(delay) timeDelay := int64(delay)

View File

@ -0,0 +1,888 @@
/* 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 proxmoxtf
import (
"strconv"
"strings"
"github.com/danitso/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
const (
dvResourceVirtualEnvironmentContainerConsoleEnabled = true
dvResourceVirtualEnvironmentContainerConsoleMode = "tty"
dvResourceVirtualEnvironmentContainerConsoleTTYCount = 2
dvResourceVirtualEnvironmentContainerInitializationDNSDomain = ""
dvResourceVirtualEnvironmentContainerInitializationDNSServer = ""
dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address = ""
dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway = ""
dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address = ""
dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway = ""
dvResourceVirtualEnvironmentContainerInitializationHostname = ""
dvResourceVirtualEnvironmentContainerInitializationUserAccountPassword = ""
dvResourceVirtualEnvironmentContainerCPUArchitecture = "amd64"
dvResourceVirtualEnvironmentContainerCPUCores = 1
dvResourceVirtualEnvironmentContainerCPUUnits = 1024
dvResourceVirtualEnvironmentContainerDescription = ""
dvResourceVirtualEnvironmentContainerDiskDatastoreID = "local-lvm"
dvResourceVirtualEnvironmentContainerDiskFileFormat = "qcow2"
dvResourceVirtualEnvironmentContainerDiskFileID = ""
dvResourceVirtualEnvironmentContainerDiskSize = 8
dvResourceVirtualEnvironmentContainerDiskSpeedRead = 0
dvResourceVirtualEnvironmentContainerDiskSpeedReadBurstable = 0
dvResourceVirtualEnvironmentContainerDiskSpeedWrite = 0
dvResourceVirtualEnvironmentContainerDiskSpeedWriteBurstable = 0
dvResourceVirtualEnvironmentContainerMemoryDedicated = 512
dvResourceVirtualEnvironmentContainerMemorySwap = 0
dvResourceVirtualEnvironmentContainerNetworkInterfaceBridge = "vmbr0"
dvResourceVirtualEnvironmentContainerNetworkInterfaceEnabled = true
dvResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress = ""
dvResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit = 0
dvResourceVirtualEnvironmentContainerNetworkInterfaceVLANID = 0
dvResourceVirtualEnvironmentContainerOperatingSystemType = "unmanaged"
dvResourceVirtualEnvironmentContainerPoolID = ""
dvResourceVirtualEnvironmentContainerStarted = true
dvResourceVirtualEnvironmentContainerVMID = -1
mkResourceVirtualEnvironmentContainerConsole = "console"
mkResourceVirtualEnvironmentContainerConsoleEnabled = "enabled"
mkResourceVirtualEnvironmentContainerConsoleMode = "type"
mkResourceVirtualEnvironmentContainerConsoleTTYCount = "tty_count"
mkResourceVirtualEnvironmentContainerCPU = "cpu"
mkResourceVirtualEnvironmentContainerCPUArchitecture = "architecture"
mkResourceVirtualEnvironmentContainerCPUCores = "cores"
mkResourceVirtualEnvironmentContainerCPUUnits = "units"
mkResourceVirtualEnvironmentContainerDescription = "description"
mkResourceVirtualEnvironmentContainerInitialization = "initialization"
mkResourceVirtualEnvironmentContainerInitializationDNS = "dns"
mkResourceVirtualEnvironmentContainerInitializationDNSDomain = "domain"
mkResourceVirtualEnvironmentContainerInitializationDNSServer = "server"
mkResourceVirtualEnvironmentContainerInitializationHostname = "hostname"
mkResourceVirtualEnvironmentContainerInitializationIPConfig = "ip_config"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4 = "ipv4"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address = "address"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway = "gateway"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6 = "ipv6"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address = "address"
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway = "gateway"
mkResourceVirtualEnvironmentContainerInitializationUserAccount = "user_account"
mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys = "keys"
mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword = "password"
mkResourceVirtualEnvironmentContainerInitializationUserAccountUsername = "username"
mkResourceVirtualEnvironmentContainerMemory = "memory"
mkResourceVirtualEnvironmentContainerMemoryDedicated = "dedicated"
mkResourceVirtualEnvironmentContainerMemorySwap = "swap"
mkResourceVirtualEnvironmentContainerNetworkInterface = "network_device"
mkResourceVirtualEnvironmentContainerNetworkInterfaceBridge = "bridge"
mkResourceVirtualEnvironmentContainerNetworkInterfaceEnabled = "enabled"
mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress = "mac_address"
mkResourceVirtualEnvironmentContainerNetworkInterfaceName = "name"
mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit = "rate_limit"
mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID = "vlan_id"
mkResourceVirtualEnvironmentContainerNodeName = "node_name"
mkResourceVirtualEnvironmentContainerOperatingSystem = "operating_system"
mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID = "template_file_id"
mkResourceVirtualEnvironmentContainerOperatingSystemType = "type"
mkResourceVirtualEnvironmentContainerPoolID = "pool_id"
mkResourceVirtualEnvironmentContainerStarted = "started"
mkResourceVirtualEnvironmentContainerVMID = "vm_id"
)
func resourceVirtualEnvironmentContainer() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerConsole: &schema.Schema{
Type: schema.TypeList,
Description: "The console configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
defaultList := make([]interface{}, 1)
defaultMap := map[string]interface{}{}
defaultMap[mkResourceVirtualEnvironmentContainerConsoleEnabled] = dvResourceVirtualEnvironmentContainerConsoleEnabled
defaultMap[mkResourceVirtualEnvironmentContainerConsoleMode] = dvResourceVirtualEnvironmentContainerConsoleMode
defaultMap[mkResourceVirtualEnvironmentContainerConsoleTTYCount] = dvResourceVirtualEnvironmentContainerConsoleTTYCount
defaultList[0] = defaultMap
return defaultList, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerConsoleEnabled: {
Type: schema.TypeBool,
Description: "Whether to enable the console device",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleEnabled,
},
mkResourceVirtualEnvironmentContainerConsoleMode: {
Type: schema.TypeString,
Description: "The console mode",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleMode,
ValidateFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(),
},
mkResourceVirtualEnvironmentContainerConsoleTTYCount: {
Type: schema.TypeInt,
Description: "The number of available TTY",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleTTYCount,
ValidateFunc: validation.IntBetween(0, 6),
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerCPU: &schema.Schema{
Type: schema.TypeList,
Description: "The CPU allocation",
Optional: true,
DefaultFunc: func() (interface{}, error) {
defaultList := make([]interface{}, 1)
defaultMap := map[string]interface{}{}
defaultMap[mkResourceVirtualEnvironmentContainerCPUArchitecture] = dvResourceVirtualEnvironmentContainerCPUArchitecture
defaultMap[mkResourceVirtualEnvironmentContainerCPUCores] = dvResourceVirtualEnvironmentContainerCPUCores
defaultMap[mkResourceVirtualEnvironmentContainerCPUUnits] = dvResourceVirtualEnvironmentContainerCPUUnits
defaultList[0] = defaultMap
return defaultList, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerCPUArchitecture: {
Type: schema.TypeString,
Description: "The CPU architecture",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUArchitecture,
ValidateFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(),
},
mkResourceVirtualEnvironmentContainerCPUCores: {
Type: schema.TypeInt,
Description: "The number of CPU cores",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUCores,
ValidateFunc: validation.IntBetween(1, 128),
},
mkResourceVirtualEnvironmentContainerCPUUnits: {
Type: schema.TypeInt,
Description: "The CPU units",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUUnits,
ValidateFunc: validation.IntBetween(0, 500000),
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerDescription: {
Type: schema.TypeString,
Description: "The description",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerDescription,
},
mkResourceVirtualEnvironmentContainerInitialization: &schema.Schema{
Type: schema.TypeList,
Description: "The initialization configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationDNS: {
Type: schema.TypeList,
Description: "The DNS configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationDNSDomain: {
Type: schema.TypeString,
Description: "The DNS search domain",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationDNSDomain,
},
mkResourceVirtualEnvironmentContainerInitializationDNSServer: {
Type: schema.TypeString,
Description: "The DNS server",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationDNSServer,
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerInitializationHostname: {
Type: schema.TypeString,
Description: "The hostname",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationHostname,
},
mkResourceVirtualEnvironmentContainerInitializationIPConfig: {
Type: schema.TypeList,
Description: "The IP configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4: {
Type: schema.TypeList,
Description: "The IPv4 configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address: {
Type: schema.TypeString,
Description: "The IPv4 address",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address,
},
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway: {
Type: schema.TypeString,
Description: "The IPv4 gateway",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway,
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6: {
Type: schema.TypeList,
Description: "The IPv6 configuration",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address: {
Type: schema.TypeString,
Description: "The IPv6 address",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address,
},
mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway: {
Type: schema.TypeString,
Description: "The IPv6 gateway",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway,
},
},
},
MaxItems: 1,
MinItems: 0,
},
},
},
MaxItems: 8,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerInitializationUserAccount: {
Type: schema.TypeList,
Description: "The user account configuration",
Optional: true,
ForceNew: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys: {
Type: schema.TypeList,
Description: "The SSH keys",
Optional: true,
ForceNew: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
Elem: &schema.Schema{Type: schema.TypeString},
},
mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword: {
Type: schema.TypeString,
Description: "The SSH password",
Optional: true,
ForceNew: true,
Sensitive: true,
Default: dvResourceVirtualEnvironmentContainerInitializationUserAccountPassword,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return strings.ReplaceAll(old, "*", "") == ""
},
},
},
},
MaxItems: 1,
MinItems: 0,
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerMemory: &schema.Schema{
Type: schema.TypeList,
Description: "The memory allocation",
Optional: true,
DefaultFunc: func() (interface{}, error) {
defaultList := make([]interface{}, 1)
defaultMap := map[string]interface{}{}
defaultMap[mkResourceVirtualEnvironmentContainerMemoryDedicated] = dvResourceVirtualEnvironmentContainerMemoryDedicated
defaultMap[mkResourceVirtualEnvironmentContainerMemorySwap] = dvResourceVirtualEnvironmentContainerMemorySwap
defaultList[0] = defaultMap
return defaultList, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerMemoryDedicated: {
Type: schema.TypeInt,
Description: "The dedicated memory in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemoryDedicated,
ValidateFunc: validation.IntBetween(16, 268435456),
},
mkResourceVirtualEnvironmentContainerMemorySwap: {
Type: schema.TypeInt,
Description: "The swap size in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemorySwap,
ValidateFunc: validation.IntBetween(0, 268435456),
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerNetworkInterface: &schema.Schema{
Type: schema.TypeList,
Description: "The network interfaces",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return make([]interface{}, 1), nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerNetworkInterfaceBridge: {
Type: schema.TypeString,
Description: "The bridge",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceBridge,
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceEnabled: {
Type: schema.TypeBool,
Description: "Whether to enable the network device",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceEnabled,
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress: {
Type: schema.TypeString,
Description: "The MAC address",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return new == ""
},
ValidateFunc: getMACAddressValidator(),
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceName: {
Type: schema.TypeString,
Description: "The network interface name",
Required: true,
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit: {
Type: schema.TypeFloat,
Description: "The rate limit in megabytes per second",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit,
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID: {
Type: schema.TypeInt,
Description: "The VLAN identifier",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceVLANID,
},
},
},
MaxItems: 8,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerNodeName: &schema.Schema{
Type: schema.TypeString,
Description: "The node name",
Required: true,
ForceNew: true,
},
mkResourceVirtualEnvironmentContainerOperatingSystem: &schema.Schema{
Type: schema.TypeList,
Description: "The operating system configuration",
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID: {
Type: schema.TypeString,
Description: "The ID of an OS template file",
Required: true,
ForceNew: true,
ValidateFunc: getFileIDValidator(),
},
mkResourceVirtualEnvironmentContainerOperatingSystemType: {
Type: schema.TypeString,
Description: "The type",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerOperatingSystemType,
ValidateFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(),
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerPoolID: {
Type: schema.TypeString,
Description: "The ID of the pool to assign the virtual machine to",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentContainerPoolID,
},
mkResourceVirtualEnvironmentContainerStarted: {
Type: schema.TypeBool,
Description: "Whether to start the container",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerStarted,
},
mkResourceVirtualEnvironmentContainerVMID: {
Type: schema.TypeInt,
Description: "The VM identifier",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentContainerVMID,
ValidateFunc: getVMIDValidator(),
},
},
Create: resourceVirtualEnvironmentContainerCreate,
Read: resourceVirtualEnvironmentContainerRead,
Update: resourceVirtualEnvironmentContainerUpdate,
Delete: resourceVirtualEnvironmentContainerDelete,
}
}
func resourceVirtualEnvironmentContainerCreate(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
resource := resourceVirtualEnvironmentContainer()
consoleBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true)
if err != nil {
return err
}
consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool))
consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string)
consoleTTYCount := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleTTYCount].(int)
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerCPU}, 0, true)
if err != nil {
return err
}
cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string)
cpuCores := cpuBlock[mkResourceVirtualEnvironmentContainerCPUCores].(int)
cpuUnits := cpuBlock[mkResourceVirtualEnvironmentContainerCPUUnits].(int)
description := d.Get(mkResourceVirtualEnvironmentContainerDescription).(string)
initialization := d.Get(mkResourceVirtualEnvironmentContainerInitialization).([]interface{})
initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain
initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer
initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname
initializationIPConfigIPv4Address := []string{}
initializationIPConfigIPv4Gateway := []string{}
initializationIPConfigIPv6Address := []string{}
initializationIPConfigIPv6Gateway := []string{}
initializationUserAccountKeys := proxmox.VirtualEnvironmentContainerCustomSSHKeys{}
initializationUserAccountPassword := dvResourceVirtualEnvironmentContainerInitializationUserAccountPassword
if len(initialization) > 0 {
initializationBlock := initialization[0].(map[string]interface{})
initializationDNS := initializationBlock[mkResourceVirtualEnvironmentContainerInitializationDNS].([]interface{})
if len(initializationDNS) > 0 {
initializationDNSBlock := initializationDNS[0].(map[string]interface{})
initializationDNSDomain = initializationDNSBlock[mkResourceVirtualEnvironmentContainerInitializationDNSDomain].(string)
initializationDNSServer = initializationDNSBlock[mkResourceVirtualEnvironmentContainerInitializationDNSServer].(string)
}
initializationHostname = initializationBlock[mkResourceVirtualEnvironmentContainerInitializationHostname].(string)
initializationIPConfig := initializationBlock[mkResourceVirtualEnvironmentContainerInitializationIPConfig].([]interface{})
for _, c := range initializationIPConfig {
configBlock := c.(map[string]interface{})
ipv4 := configBlock[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4].([]interface{})
if len(ipv4) > 0 {
ipv4Block := ipv4[0].(map[string]interface{})
initializationIPConfigIPv4Address = append(initializationIPConfigIPv4Address, ipv4Block[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address].(string))
initializationIPConfigIPv4Gateway = append(initializationIPConfigIPv4Gateway, ipv4Block[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway].(string))
} else {
initializationIPConfigIPv4Address = append(initializationIPConfigIPv4Address, "")
initializationIPConfigIPv4Gateway = append(initializationIPConfigIPv4Gateway, "")
}
ipv6 := configBlock[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6].([]interface{})
if len(ipv6) > 0 {
ipv6Block := ipv6[0].(map[string]interface{})
initializationIPConfigIPv6Address = append(initializationIPConfigIPv6Address, ipv6Block[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address].(string))
initializationIPConfigIPv6Gateway = append(initializationIPConfigIPv6Gateway, ipv6Block[mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway].(string))
} else {
initializationIPConfigIPv6Address = append(initializationIPConfigIPv6Address, "")
initializationIPConfigIPv6Gateway = append(initializationIPConfigIPv6Gateway, "")
}
}
initializationUserAccount := initializationBlock[mkResourceVirtualEnvironmentContainerInitializationUserAccount].([]interface{})
if len(initializationUserAccount) > 0 {
initializationUserAccountBlock := initializationUserAccount[0].(map[string]interface{})
keys := initializationUserAccountBlock[mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys].([]interface{})
initializationUserAccountKeys := make(proxmox.VirtualEnvironmentContainerCustomSSHKeys, len(keys))
for ki, kv := range keys {
initializationUserAccountKeys[ki] = kv.(string)
}
initializationUserAccountPassword = initializationUserAccountBlock[mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword].(string)
}
}
memoryBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerMemory}, 0, true)
if err != nil {
return err
}
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int)
memorySwap := memoryBlock[mkResourceVirtualEnvironmentContainerMemorySwap].(int)
networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
networkInterfaceArray := make(proxmox.VirtualEnvironmentContainerCustomNetworkInterfaceArray, len(networkInterface))
for ni, nv := range networkInterface {
networkInterfaceMap := nv.(map[string]interface{})
networkInterfaceObject := proxmox.VirtualEnvironmentContainerCustomNetworkInterface{}
bridge := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceBridge].(string)
enabled := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceEnabled].(bool)
macAddress := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress].(string)
name := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceName].(string)
rateLimit := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit].(int)
vlanID := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID].(int)
if bridge != "" {
networkInterfaceObject.Bridge = &bridge
}
networkInterfaceObject.Enabled = enabled
if len(initializationIPConfigIPv4Address) > ni {
if initializationIPConfigIPv4Address[ni] != "" {
networkInterfaceObject.IPv4Address = &initializationIPConfigIPv4Address[ni]
}
if initializationIPConfigIPv4Gateway[ni] != "" {
networkInterfaceObject.IPv4Gateway = &initializationIPConfigIPv4Gateway[ni]
}
if initializationIPConfigIPv6Address[ni] != "" {
networkInterfaceObject.IPv6Address = &initializationIPConfigIPv6Address[ni]
}
if initializationIPConfigIPv6Gateway[ni] != "" {
networkInterfaceObject.IPv6Gateway = &initializationIPConfigIPv6Gateway[ni]
}
}
if macAddress != "" {
networkInterfaceObject.MACAddress = &macAddress
}
if name != "" {
networkInterfaceObject.Name = name
}
if rateLimit != 0 {
networkInterfaceObject.RateLimit = &rateLimit
}
if vlanID != 0 {
networkInterfaceObject.Tag = &vlanID
}
networkInterfaceArray[ni] = networkInterfaceObject
}
operatingSystem, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerOperatingSystem}, 0, true)
if err != nil {
return err
}
operatingSystemTemplateFileID := operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID].(string)
operatingSystemType := operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType].(string)
poolID := d.Get(mkResourceVirtualEnvironmentContainerPoolID).(string)
started := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool))
vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int)
if vmID == -1 {
vmIDNew, err := veClient.GetVMID()
if err != nil {
return err
}
vmID = *vmIDNew
}
// Attempt to create the resource using the retrieved values.
body := proxmox.VirtualEnvironmentContainerCreateRequestBody{
ConsoleEnabled: &consoleEnabled,
ConsoleMode: &consoleMode,
CPUArchitecture: &cpuArchitecture,
CPUCores: &cpuCores,
CPUUnits: &cpuUnits,
DedicatedMemory: &memoryDedicated,
NetworkInterfaces: networkInterfaceArray,
OSTemplateFileVolume: operatingSystemTemplateFileID,
OSType: &operatingSystemType,
StartOnBoot: &started,
Swap: &memorySwap,
TTY: &consoleTTYCount,
VMID: vmID,
}
if description != "" {
body.Description = &description
}
if initializationDNSDomain != "" {
body.DNSDomain = &initializationDNSDomain
}
if initializationDNSServer != "" {
body.DNSServer = &initializationDNSServer
}
if initializationHostname != "" {
body.Hostname = &initializationHostname
}
if len(initializationUserAccountKeys) > 0 {
body.SSHKeys = &initializationUserAccountKeys
}
if initializationUserAccountPassword != "" {
body.Password = &initializationUserAccountPassword
}
if poolID != "" {
body.PoolID = &poolID
}
err = veClient.CreateContainer(nodeName, &body)
if err != nil {
return err
}
d.SetId(strconv.Itoa(vmID))
return resourceVirtualEnvironmentContainerCreateStart(d, m)
}
func resourceVirtualEnvironmentContainerCreateStart(d *schema.ResourceData, m interface{}) error {
started := d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool)
if !started {
return resourceVirtualEnvironmentContainerRead(d, m)
}
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
}
// Start the container and wait for it to reach a running state before continuing.
err = veClient.StartContainer(nodeName, vmID)
if err != nil {
return err
}
err = veClient.WaitForContainerState(nodeName, vmID, "running", 120, 5)
if err != nil {
return err
}
return resourceVirtualEnvironmentContainerRead(d, m)
}
func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"console",
"shell",
"tty",
}, false)
}
func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"amd64",
"arm64",
"armhf",
"i386",
}, false)
}
func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"alpine",
"archlinux",
"centos",
"debian",
"fedora",
"gentoo",
"opensuse",
"ubuntu",
"unmanaged",
}, false)
}
func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
}
// Retrieve the entire configuration in order to compare it to the state.
_, err = veClient.GetContainer(nodeName, vmID)
if err != nil {
if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("")
return nil
}
return err
}
return nil
}
func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
}
// Retrieve the entire configuration as we need to process certain values.
_, err = veClient.GetContainer(nodeName, vmID)
if err != nil {
return err
}
return resourceVirtualEnvironmentContainerRead(d, m)
}
func resourceVirtualEnvironmentContainerDelete(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
}
err = veClient.DeleteContainer(nodeName, vmID)
if err != nil {
if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("")
return nil
}
return err
}
d.SetId("")
return nil
}

View File

@ -79,6 +79,7 @@ func resourceVirtualEnvironmentHosts() *schema.Resource {
}, },
}, },
}, },
MinItems: 1,
}, },
mkResourceVirtualEnvironmentHostsHostnames: &schema.Schema{ mkResourceVirtualEnvironmentHostsHostnames: &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMACPI, mkResourceVirtualEnvironmentVMACPI,
mkResourceVirtualEnvironmentVMBIOS, mkResourceVirtualEnvironmentVMBIOS,
mkResourceVirtualEnvironmentVMCDROM, mkResourceVirtualEnvironmentVMCDROM,
mkResourceVirtualEnvironmentVMCloudInit, mkResourceVirtualEnvironmentVMInitialization,
mkResourceVirtualEnvironmentVMCPU, mkResourceVirtualEnvironmentVMCPU,
mkResourceVirtualEnvironmentVMDescription, mkResourceVirtualEnvironmentVMDescription,
mkResourceVirtualEnvironmentVMDisk, mkResourceVirtualEnvironmentVMDisk,
@ -39,7 +39,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMMemory, mkResourceVirtualEnvironmentVMMemory,
mkResourceVirtualEnvironmentVMName, mkResourceVirtualEnvironmentVMName,
mkResourceVirtualEnvironmentVMNetworkDevice, mkResourceVirtualEnvironmentVMNetworkDevice,
mkResourceVirtualEnvironmentVMOSType, mkResourceVirtualEnvironmentVMOperatingSystem,
mkResourceVirtualEnvironmentVMPoolID, mkResourceVirtualEnvironmentVMPoolID,
mkResourceVirtualEnvironmentVMStarted, mkResourceVirtualEnvironmentVMStarted,
mkResourceVirtualEnvironmentVMTabletDevice, mkResourceVirtualEnvironmentVMTabletDevice,
@ -58,7 +58,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMAgent, mkResourceVirtualEnvironmentVMAgent,
mkResourceVirtualEnvironmentVMBIOS, mkResourceVirtualEnvironmentVMBIOS,
mkResourceVirtualEnvironmentVMCDROM, mkResourceVirtualEnvironmentVMCDROM,
mkResourceVirtualEnvironmentVMCloudInit, mkResourceVirtualEnvironmentVMInitialization,
mkResourceVirtualEnvironmentVMCPU, mkResourceVirtualEnvironmentVMCPU,
mkResourceVirtualEnvironmentVMDescription, mkResourceVirtualEnvironmentVMDescription,
mkResourceVirtualEnvironmentVMDisk, mkResourceVirtualEnvironmentVMDisk,
@ -70,7 +70,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMNetworkDevice, mkResourceVirtualEnvironmentVMNetworkDevice,
mkResourceVirtualEnvironmentVMMACAddresses, mkResourceVirtualEnvironmentVMMACAddresses,
mkResourceVirtualEnvironmentVMNetworkInterfaceNames, mkResourceVirtualEnvironmentVMNetworkInterfaceNames,
mkResourceVirtualEnvironmentVMOSType, mkResourceVirtualEnvironmentVMOperatingSystem,
mkResourceVirtualEnvironmentVMPoolID, mkResourceVirtualEnvironmentVMPoolID,
mkResourceVirtualEnvironmentVMStarted, mkResourceVirtualEnvironmentVMStarted,
mkResourceVirtualEnvironmentVMTabletDevice, mkResourceVirtualEnvironmentVMTabletDevice,
@ -92,7 +92,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
schema.TypeList, schema.TypeList,
schema.TypeList, schema.TypeList,
schema.TypeList, schema.TypeList,
schema.TypeString, schema.TypeList,
schema.TypeString, schema.TypeString,
schema.TypeBool, schema.TypeBool,
schema.TypeBool, schema.TypeBool,
@ -132,111 +132,10 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
schema.TypeString, schema.TypeString,
}) })
cloudInitSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCloudInit)
testRequiredArguments(t, cloudInitSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitUserAccount,
})
testOptionalArguments(t, cloudInitSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitDNS,
mkResourceVirtualEnvironmentVMCloudInitIPConfig,
})
testSchemaValueTypes(t, cloudInitSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitDNS,
mkResourceVirtualEnvironmentVMCloudInitIPConfig,
mkResourceVirtualEnvironmentVMCloudInitUserAccount,
}, []schema.ValueType{
schema.TypeList,
schema.TypeList,
schema.TypeList,
})
cloudInitDNSSchema := testNestedSchemaExistence(t, cloudInitSchema, mkResourceVirtualEnvironmentVMCloudInitDNS)
testOptionalArguments(t, cloudInitDNSSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitDNSDomain,
mkResourceVirtualEnvironmentVMCloudInitDNSServer,
})
testSchemaValueTypes(t, cloudInitDNSSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitDNSDomain,
mkResourceVirtualEnvironmentVMCloudInitDNSServer,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
cloudInitIPConfigSchema := testNestedSchemaExistence(t, cloudInitSchema, mkResourceVirtualEnvironmentVMCloudInitIPConfig)
testOptionalArguments(t, cloudInitIPConfigSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6,
})
testSchemaValueTypes(t, cloudInitIPConfigSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6,
}, []schema.ValueType{
schema.TypeList,
schema.TypeList,
})
cloudInitIPConfigIPv4Schema := testNestedSchemaExistence(t, cloudInitIPConfigSchema, mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4)
testOptionalArguments(t, cloudInitIPConfigIPv4Schema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway,
})
testSchemaValueTypes(t, cloudInitIPConfigIPv4Schema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
cloudInitIPConfigIPv6Schema := testNestedSchemaExistence(t, cloudInitIPConfigSchema, mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6)
testOptionalArguments(t, cloudInitIPConfigIPv6Schema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway,
})
testSchemaValueTypes(t, cloudInitIPConfigIPv6Schema, []string{
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address,
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
cloudInitUserAccountSchema := testNestedSchemaExistence(t, cloudInitSchema, mkResourceVirtualEnvironmentVMCloudInitUserAccount)
testRequiredArguments(t, cloudInitUserAccountSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys,
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername,
})
testOptionalArguments(t, cloudInitUserAccountSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword,
})
testSchemaValueTypes(t, cloudInitUserAccountSchema, []string{
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys,
mkResourceVirtualEnvironmentVMCloudInitUserAccountPassword,
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername,
}, []schema.ValueType{
schema.TypeList,
schema.TypeString,
schema.TypeString,
})
cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU) cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU)
testOptionalArguments(t, cpuSchema, []string{ testOptionalArguments(t, cpuSchema, []string{
mkResourceVirtualEnvironmentVMCPUArchitecture,
mkResourceVirtualEnvironmentVMCPUCores, mkResourceVirtualEnvironmentVMCPUCores,
mkResourceVirtualEnvironmentVMCPUFlags, mkResourceVirtualEnvironmentVMCPUFlags,
mkResourceVirtualEnvironmentVMCPUHotplugged, mkResourceVirtualEnvironmentVMCPUHotplugged,
@ -246,6 +145,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
}) })
testSchemaValueTypes(t, cpuSchema, []string{ testSchemaValueTypes(t, cpuSchema, []string{
mkResourceVirtualEnvironmentVMCPUArchitecture,
mkResourceVirtualEnvironmentVMCPUCores, mkResourceVirtualEnvironmentVMCPUCores,
mkResourceVirtualEnvironmentVMCPUFlags, mkResourceVirtualEnvironmentVMCPUFlags,
mkResourceVirtualEnvironmentVMCPUHotplugged, mkResourceVirtualEnvironmentVMCPUHotplugged,
@ -253,6 +153,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMCPUType, mkResourceVirtualEnvironmentVMCPUType,
mkResourceVirtualEnvironmentVMCPUUnits, mkResourceVirtualEnvironmentVMCPUUnits,
}, []schema.ValueType{ }, []schema.ValueType{
schema.TypeString,
schema.TypeInt, schema.TypeInt,
schema.TypeList, schema.TypeList,
schema.TypeInt, schema.TypeInt,
@ -303,6 +204,102 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
schema.TypeInt, schema.TypeInt,
}) })
initializationSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMInitialization)
testOptionalArguments(t, initializationSchema, []string{
mkResourceVirtualEnvironmentVMInitializationDNS,
mkResourceVirtualEnvironmentVMInitializationIPConfig,
mkResourceVirtualEnvironmentVMInitializationUserAccount,
})
testSchemaValueTypes(t, initializationSchema, []string{
mkResourceVirtualEnvironmentVMInitializationDNS,
mkResourceVirtualEnvironmentVMInitializationIPConfig,
mkResourceVirtualEnvironmentVMInitializationUserAccount,
}, []schema.ValueType{
schema.TypeList,
schema.TypeList,
schema.TypeList,
})
initializationDNSSchema := testNestedSchemaExistence(t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationDNS)
testOptionalArguments(t, initializationDNSSchema, []string{
mkResourceVirtualEnvironmentVMInitializationDNSDomain,
mkResourceVirtualEnvironmentVMInitializationDNSServer,
})
testSchemaValueTypes(t, initializationDNSSchema, []string{
mkResourceVirtualEnvironmentVMInitializationDNSDomain,
mkResourceVirtualEnvironmentVMInitializationDNSServer,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
initializationIPConfigSchema := testNestedSchemaExistence(t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationIPConfig)
testOptionalArguments(t, initializationIPConfigSchema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6,
})
testSchemaValueTypes(t, initializationIPConfigSchema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6,
}, []schema.ValueType{
schema.TypeList,
schema.TypeList,
})
initializationIPConfigIPv4Schema := testNestedSchemaExistence(t, initializationIPConfigSchema, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4)
testOptionalArguments(t, initializationIPConfigIPv4Schema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway,
})
testSchemaValueTypes(t, initializationIPConfigIPv4Schema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
initializationIPConfigIPv6Schema := testNestedSchemaExistence(t, initializationIPConfigSchema, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6)
testOptionalArguments(t, initializationIPConfigIPv6Schema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway,
})
testSchemaValueTypes(t, initializationIPConfigIPv6Schema, []string{
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address,
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway,
}, []schema.ValueType{
schema.TypeString,
schema.TypeString,
})
initializationUserAccountSchema := testNestedSchemaExistence(t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationUserAccount)
testOptionalArguments(t, initializationUserAccountSchema, []string{
mkResourceVirtualEnvironmentVMInitializationUserAccountKeys,
mkResourceVirtualEnvironmentVMInitializationUserAccountPassword,
mkResourceVirtualEnvironmentVMInitializationUserAccountUsername,
})
testSchemaValueTypes(t, initializationUserAccountSchema, []string{
mkResourceVirtualEnvironmentVMInitializationUserAccountKeys,
mkResourceVirtualEnvironmentVMInitializationUserAccountPassword,
mkResourceVirtualEnvironmentVMInitializationUserAccountUsername,
}, []schema.ValueType{
schema.TypeList,
schema.TypeString,
schema.TypeString,
})
memorySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory) memorySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory)
testOptionalArguments(t, memorySchema, []string{ testOptionalArguments(t, memorySchema, []string{
@ -348,6 +345,18 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
schema.TypeInt, schema.TypeInt,
}) })
operatingSystemSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMOperatingSystem)
testOptionalArguments(t, operatingSystemSchema, []string{
mkResourceVirtualEnvironmentVMOperatingSystemType,
})
testSchemaValueTypes(t, operatingSystemSchema, []string{
mkResourceVirtualEnvironmentVMOperatingSystemType,
}, []schema.ValueType{
schema.TypeString,
})
vgaSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMVGA) vgaSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMVGA)
testOptionalArguments(t, vgaSchema, []string{ testOptionalArguments(t, vgaSchema, []string{

View File

@ -225,23 +225,6 @@ func getNetworkDeviceModelValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false) return validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false)
} }
func getOSTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"l24",
"l26",
"other",
"solaris",
"w2k",
"w2k3",
"w2k8",
"win7",
"win8",
"win10",
"wvista",
"wxp",
}, false)
}
func getQEMUAgentTypeValidator() schema.SchemaValidateFunc { func getQEMUAgentTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{"isa", "virtio"}, false) return validation.StringInSlice([]string{"isa", "virtio"}, false)
} }