mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-23 03:48:35 +00:00
Initial work on VM resource implementation
This commit is contained in:
parent
b5c91c08f8
commit
96d139fcb4
@ -18,3 +18,4 @@ FEATURES:
|
|||||||
* **New Resource:** `proxmox_virtual_environment_pool`
|
* **New Resource:** `proxmox_virtual_environment_pool`
|
||||||
* **New Resource:** `proxmox_virtual_environment_role`
|
* **New Resource:** `proxmox_virtual_environment_role`
|
||||||
* **New Resource:** `proxmox_virtual_environment_user`
|
* **New Resource:** `proxmox_virtual_environment_user`
|
||||||
|
* **New Resource:** `proxmox_virtual_environment_vm`
|
||||||
|
49
README.md
49
README.md
@ -31,6 +31,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)
|
||||||
- [Developing the Provider](#developing-the-provider)
|
- [Developing the Provider](#developing-the-provider)
|
||||||
- [Testing the Provider](#testing-the-provider)
|
- [Testing the Provider](#testing-the-provider)
|
||||||
|
|
||||||
@ -310,6 +311,54 @@ 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)
|
||||||
|
|
||||||
|
###### Arguments
|
||||||
|
* `cdrom` - (Optional) The CDROM configuration
|
||||||
|
* `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)
|
||||||
|
* `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` - (Optional) The user account configuration
|
||||||
|
* `keys` - (Optional) The SSH keys
|
||||||
|
* `username` - (Optional) The SSH username
|
||||||
|
* `cpu` - (Optional) The CPU configuration
|
||||||
|
* `cores` - (Optional) The number of CPU cores (defaults to `1`)
|
||||||
|
* `sockets` - (Optional) The number of CPU sockets (defaults to `1`)
|
||||||
|
* `disk` - (Optional) The disk configuration (multiple blocks supported)
|
||||||
|
* `datastore_id` - (Optional) The ID of the datastore to create the disk in (defaults to `local-lvm`)
|
||||||
|
* `enabled` - (Optional) Whether to enable the disk (defaults to `true`)
|
||||||
|
* `file_format` - (Optional) The file format (defaults to `qcow2`)
|
||||||
|
* `file_id` - (Optional) The file ID for a disk image
|
||||||
|
* `size` - (Optional) The disk size in gigabytes (defaults to `8`)
|
||||||
|
* `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`)
|
||||||
|
* `memory` - (Optional) The memory configuration
|
||||||
|
* `dedicated` - (Optional) The dedicated memory in megabytes (defaults to `512`)
|
||||||
|
* `floating` - (Optional) The floating memory in megabytes (defaults to `0`)
|
||||||
|
* `shared` - (Optional) The shared memory in megabytes (defaults to `0`)
|
||||||
|
* `name` - (Optional) The virtual machine name
|
||||||
|
* `network_device` - (Optional) The network device configuration (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
|
||||||
|
* `model` - (Optional) The network device model (defaults to `virtio`)
|
||||||
|
* `vlan_id` - (Optional) The VLAN identifier
|
||||||
|
* `node_name` - (Required) The name of the node to assign the virtual machine to
|
||||||
|
* `os_type` - (Optional) The OS type (defaults to `other`)
|
||||||
|
* `vm_id` - (Optional) The virtual machine ID
|
||||||
|
|
||||||
|
###### Attributes
|
||||||
|
This resource doesn't expose any additional attributes.
|
||||||
|
|
||||||
## Developing the Provider
|
## Developing the Provider
|
||||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.13+ is *required*). You'll also need to correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`.
|
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.13+ is *required*). You'll also need to correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`.
|
||||||
|
|
||||||
|
27
example/resource_virtual_environment_vm.tf
Normal file
27
example/resource_virtual_environment_vm.tf
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
resource "proxmox_virtual_environment_vm" "example" {
|
||||||
|
cloud_init {
|
||||||
|
dns {
|
||||||
|
server = "1.1.1.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_config {
|
||||||
|
ipv4 {
|
||||||
|
address = "dhcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_account {
|
||||||
|
keys = ["${trimspace(tls_private_key.example.public_key_openssh)}"]
|
||||||
|
username = "ubuntu"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
network_device {}
|
||||||
|
|
||||||
|
node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "tls_private_key" "example" {
|
||||||
|
algorithm = "RSA"
|
||||||
|
rsa_bits = 2048
|
||||||
|
}
|
@ -36,6 +36,34 @@ func (c *VirtualEnvironmentClient) GetVM(nodeName string, vmID int) (*VirtualEnv
|
|||||||
return resBody.Data, nil
|
return resBody.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetVMID retrieves the next available VM identifier.
|
||||||
|
func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
|
||||||
|
nodes, err := c.ListNodes()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vmID := 100
|
||||||
|
|
||||||
|
VMID:
|
||||||
|
for vmID <= 2147483637 {
|
||||||
|
for _, n := range nodes {
|
||||||
|
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/status/current", url.PathEscape(n.Name), vmID), nil, nil)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
vmID += 5
|
||||||
|
|
||||||
|
continue VMID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &vmID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("Unable to retrieve the next available VM identifier")
|
||||||
|
}
|
||||||
|
|
||||||
// ListVMs retrieves a list of virtual machines.
|
// ListVMs retrieves a list of virtual machines.
|
||||||
func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) {
|
func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) {
|
||||||
return nil, errors.New("Not implemented")
|
return nil, errors.New("Not implemented")
|
||||||
|
@ -13,9 +13,9 @@ import (
|
|||||||
|
|
||||||
// CustomAgent handles QEMU agent parameters.
|
// CustomAgent handles QEMU agent parameters.
|
||||||
type CustomAgent struct {
|
type CustomAgent struct {
|
||||||
Enabled CustomBool `json:"enabled,omitempty" url:"enabled,int"`
|
Enabled *CustomBool `json:"enabled,omitempty" url:"enabled,int"`
|
||||||
TrimClonedDisks CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
|
TrimClonedDisks *CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
|
||||||
Type string `json:"type" url:"type"`
|
Type *string `json:"type" url:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomAudioDevice handles QEMU audio parameters.
|
// CustomAudioDevice handles QEMU audio parameters.
|
||||||
@ -65,6 +65,7 @@ type CustomEFIDisk struct {
|
|||||||
type CustomNetworkDevice struct {
|
type CustomNetworkDevice struct {
|
||||||
Model string `json:"model" url:"model"`
|
Model string `json:"model" url:"model"`
|
||||||
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
||||||
|
Enabled bool `json:"-" url:"-"`
|
||||||
Firewall *CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
Firewall *CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
||||||
LinkDown *CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
|
LinkDown *CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
|
||||||
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
|
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
|
||||||
@ -141,6 +142,7 @@ type CustomStorageDevice struct {
|
|||||||
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
FileVolume string `json:"file" url:"file"`
|
FileVolume string `json:"file" url:"file"`
|
||||||
|
Media *string `json:"media,omitempty" url:"media,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomStorageDevices handles QEMU SATA device parameters.
|
// CustomStorageDevices handles QEMU SATA device parameters.
|
||||||
@ -244,6 +246,7 @@ type VirtualEnvironmentVMCreateRequestBody struct {
|
|||||||
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
|
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
|
||||||
VirtualIODevices CustomVirtualIODevices `json:"virtio,omitempty" url:"virtio,omitempty"`
|
VirtualIODevices CustomVirtualIODevices `json:"virtio,omitempty" url:"virtio,omitempty"`
|
||||||
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
|
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
|
||||||
|
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
||||||
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
|
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
|
||||||
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
|
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
|
||||||
}
|
}
|
||||||
@ -338,19 +341,31 @@ type VirtualEnvironmentVMUpdateRequestBody VirtualEnvironmentVMCreateRequestBody
|
|||||||
|
|
||||||
// EncodeValues converts a CustomAgent struct to a URL vlaue.
|
// EncodeValues converts a CustomAgent struct to a URL vlaue.
|
||||||
func (r CustomAgent) EncodeValues(key string, v *url.Values) error {
|
func (r CustomAgent) EncodeValues(key string, v *url.Values) error {
|
||||||
enabled := 0
|
values := []string{}
|
||||||
|
|
||||||
if r.Enabled {
|
if r.Enabled != nil {
|
||||||
enabled = 1
|
if *r.Enabled {
|
||||||
|
values = append(values, "enabled=1")
|
||||||
|
} else {
|
||||||
|
values = append(values, "enabled=0")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trimClonedDisks := 0
|
if r.TrimClonedDisks != nil {
|
||||||
|
if *r.TrimClonedDisks {
|
||||||
if r.TrimClonedDisks {
|
values = append(values, "fstrim_cloned_disks=1")
|
||||||
trimClonedDisks = 1
|
} else {
|
||||||
|
values = append(values, "fstrim_cloned_disks=0")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Add(key, fmt.Sprintf("enabled=%d,fstrim_cloned_disks=%d,type=%s", enabled, trimClonedDisks, r.Type))
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@ -421,13 +436,7 @@ func (r CustomCloudInitConfig) EncodeValues(key string, v *url.Values) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.SSHKeys != nil {
|
if r.SSHKeys != nil {
|
||||||
keys := []string{}
|
v.Add("sshkeys", strings.ReplaceAll(url.QueryEscape(strings.Join(*r.SSHKeys, "\n")), "+", "%20"))
|
||||||
|
|
||||||
for _, pk := range *r.SSHKeys {
|
|
||||||
keys = append(keys, pk)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Add("sshkeys", strings.Join(keys, "\n"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Type != nil {
|
if r.Type != nil {
|
||||||
@ -520,8 +529,10 @@ func (r CustomNetworkDevice) EncodeValues(key string, v *url.Values) error {
|
|||||||
// EncodeValues converts a CustomNetworkDevices array to multiple URL values.
|
// EncodeValues converts a CustomNetworkDevices array to multiple URL values.
|
||||||
func (r CustomNetworkDevices) EncodeValues(key string, v *url.Values) error {
|
func (r CustomNetworkDevices) EncodeValues(key string, v *url.Values) error {
|
||||||
for i, d := range r {
|
for i, d := range r {
|
||||||
|
if d.Enabled {
|
||||||
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
|
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -745,6 +756,10 @@ func (r CustomStorageDevice) EncodeValues(key string, v *url.Values) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.Media != nil {
|
||||||
|
values = append(values, fmt.Sprintf("media=%s", *r.Media))
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(key, strings.Join(values, ","))
|
v.Add(key, strings.Join(values, ","))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -48,6 +48,7 @@ func Provider() *schema.Provider {
|
|||||||
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
||||||
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
||||||
"proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(),
|
"proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(),
|
||||||
|
"proxmox_virtual_environment_vm": resourceVirtualEnvironmentVM(),
|
||||||
},
|
},
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkProviderVirtualEnvironment: &schema.Schema{
|
mkProviderVirtualEnvironment: &schema.Schema{
|
||||||
|
@ -6,34 +6,66 @@ package proxmoxtf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/danitso/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/hashicorp/terraform/helper/validation"
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
dvResourceVirtualEnvironmentVMCDROMEnabled = false
|
||||||
|
dvResourceVirtualEnvironmentVMCDROMFileID = ""
|
||||||
|
dvResourceVirtualEnvironmentVMCloudInitDNSDomain = ""
|
||||||
|
dvResourceVirtualEnvironmentVMCloudInitDNSServer = ""
|
||||||
dvResourceVirtualEnvironmentVMCPUCores = 1
|
dvResourceVirtualEnvironmentVMCPUCores = 1
|
||||||
dvResourceVirtualEnvironmentVMCPUSockets = 1
|
dvResourceVirtualEnvironmentVMCPUSockets = 1
|
||||||
dvResourceVirtualEnvironmentVMDiskDatastoreID = "local-lvm"
|
dvResourceVirtualEnvironmentVMDiskDatastoreID = "local-lvm"
|
||||||
|
dvResourceVirtualEnvironmentVMDiskEnabled = true
|
||||||
|
dvResourceVirtualEnvironmentVMDiskFileFormat = "qcow2"
|
||||||
dvResourceVirtualEnvironmentVMDiskFileID = ""
|
dvResourceVirtualEnvironmentVMDiskFileID = ""
|
||||||
dvResourceVirtualEnvironmentVMDiskSize = 8
|
dvResourceVirtualEnvironmentVMDiskSize = 8
|
||||||
dvResourceVirtualEnvironmentVMMemoryDedicated = 256
|
dvResourceVirtualEnvironmentVMKeyboardLayout = "en-us"
|
||||||
|
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
||||||
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
||||||
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
||||||
dvResourceVirtualEnvironmentVMName = ""
|
dvResourceVirtualEnvironmentVMName = ""
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceBridge = "vmbr0"
|
dvResourceVirtualEnvironmentVMNetworkDeviceBridge = "vmbr0"
|
||||||
|
dvResourceVirtualEnvironmentVMNetworkDeviceEnabled = true
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress = ""
|
dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress = ""
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceModel = "virtio"
|
dvResourceVirtualEnvironmentVMNetworkDeviceModel = "virtio"
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceVLANID = -1
|
dvResourceVirtualEnvironmentVMNetworkDeviceVLANID = -1
|
||||||
|
dvResourceVirtualEnvironmentVMOSType = "other"
|
||||||
dvResourceVirtualEnvironmentVMVMID = -1
|
dvResourceVirtualEnvironmentVMVMID = -1
|
||||||
|
|
||||||
|
mkResourceVirtualEnvironmentVMCDROM = "cdrom"
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMEnabled = "enabled"
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMFileID = "file_id"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInit = "cloud_init"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNS = "dns"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNSDomain = "domain"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNSServer = "server"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfig = "ip_config"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4 = "ipv4"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address = "address"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway = "gateway"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6 = "ipv6"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address = "address"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway = "gateway"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccount = "user_account"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys = "keys"
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername = "username"
|
||||||
mkResourceVirtualEnvironmentVMCPU = "cpu"
|
mkResourceVirtualEnvironmentVMCPU = "cpu"
|
||||||
mkResourceVirtualEnvironmentVMCPUCores = "cores"
|
mkResourceVirtualEnvironmentVMCPUCores = "cores"
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets = "sockets"
|
mkResourceVirtualEnvironmentVMCPUSockets = "sockets"
|
||||||
mkResourceVirtualEnvironmentVMDisk = "disk"
|
mkResourceVirtualEnvironmentVMDisk = "disk"
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID = "datastore_id"
|
mkResourceVirtualEnvironmentVMDiskDatastoreID = "datastore_id"
|
||||||
|
mkResourceVirtualEnvironmentVMDiskEnabled = "enabled"
|
||||||
|
mkResourceVirtualEnvironmentVMDiskFileFormat = "file_format"
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID = "file_id"
|
mkResourceVirtualEnvironmentVMDiskFileID = "file_id"
|
||||||
mkResourceVirtualEnvironmentVMDiskSize = "size"
|
mkResourceVirtualEnvironmentVMDiskSize = "size"
|
||||||
|
mkResourceVirtualEnvironmentVMKeyboardLayout = "keyboard_layout"
|
||||||
mkResourceVirtualEnvironmentVMMemory = "memory"
|
mkResourceVirtualEnvironmentVMMemory = "memory"
|
||||||
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
||||||
mkResourceVirtualEnvironmentVMMemoryFloating = "floating"
|
mkResourceVirtualEnvironmentVMMemoryFloating = "floating"
|
||||||
@ -41,15 +73,184 @@ const (
|
|||||||
mkResourceVirtualEnvironmentVMName = "name"
|
mkResourceVirtualEnvironmentVMName = "name"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice = "network_device"
|
mkResourceVirtualEnvironmentVMNetworkDevice = "network_device"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge = "bridge"
|
mkResourceVirtualEnvironmentVMNetworkDeviceBridge = "bridge"
|
||||||
|
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled = "enabled"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress = "mac_address"
|
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress = "mac_address"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel = "model"
|
mkResourceVirtualEnvironmentVMNetworkDeviceModel = "model"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID = "vlan_id"
|
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID = "vlan_id"
|
||||||
|
mkResourceVirtualEnvironmentVMNodeName = "node_name"
|
||||||
|
mkResourceVirtualEnvironmentVMOSType = "os_type"
|
||||||
mkResourceVirtualEnvironmentVMVMID = "vm_id"
|
mkResourceVirtualEnvironmentVMVMID = "vm_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceVirtualEnvironmentVM() *schema.Resource {
|
func resourceVirtualEnvironmentVM() *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROM: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The CDROM drive",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
defaultList := make([]interface{}, 1)
|
||||||
|
defaultMap := make(map[string]interface{})
|
||||||
|
|
||||||
|
defaultMap[mkResourceVirtualEnvironmentVMCDROMEnabled] = dvResourceVirtualEnvironmentVMCDROMEnabled
|
||||||
|
defaultMap[mkResourceVirtualEnvironmentVMCDROMFileID] = dvResourceVirtualEnvironmentVMCDROMFileID
|
||||||
|
|
||||||
|
defaultList[0] = defaultMap
|
||||||
|
|
||||||
|
return defaultList, nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMEnabled: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Whether to enable the CDROM drive",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMCDROMEnabled,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMFileID: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The file id",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMCDROMFileID,
|
||||||
|
ValidateFunc: getFileIDValidator(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInit: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The cloud-init configuration",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNS: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The DNS configuration",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNSDomain: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The DNS search domain",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMCloudInitDNSDomain,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitDNSServer: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The DNS server",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMCloudInitDNSServer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfig: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The IP configuration",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The IPv4 configuration",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Address: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The IPv4 address",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv4Gateway: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The IPv4 gateway",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The IPv6 configuration",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Address: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The IPv6 address",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitIPConfigIPv6Gateway: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The IPv6 gateway",
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 8,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccount: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The user account configuration",
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountKeys: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Required: true,
|
||||||
|
Description: "The SSH keys",
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "The SSH username",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMCPU: &schema.Schema{
|
mkResourceVirtualEnvironmentVMCPU: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Description: "The CPU allocation",
|
Description: "The CPU allocation",
|
||||||
@ -84,7 +285,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxItems: 1,
|
MaxItems: 1,
|
||||||
MinItems: 1,
|
MinItems: 0,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDisk: &schema.Schema{
|
mkResourceVirtualEnvironmentVMDisk: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
@ -95,6 +296,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
defaultMap := make(map[string]interface{})
|
defaultMap := make(map[string]interface{})
|
||||||
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMDiskDatastoreID] = dvResourceVirtualEnvironmentVMDiskDatastoreID
|
defaultMap[mkResourceVirtualEnvironmentVMDiskDatastoreID] = dvResourceVirtualEnvironmentVMDiskDatastoreID
|
||||||
|
defaultMap[mkResourceVirtualEnvironmentVMDiskFileFormat] = dvResourceVirtualEnvironmentVMDiskFileFormat
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMDiskFileID] = dvResourceVirtualEnvironmentVMDiskFileID
|
defaultMap[mkResourceVirtualEnvironmentVMDiskFileID] = dvResourceVirtualEnvironmentVMDiskFileID
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMDiskSize] = dvResourceVirtualEnvironmentVMDiskSize
|
defaultMap[mkResourceVirtualEnvironmentVMDiskSize] = dvResourceVirtualEnvironmentVMDiskSize
|
||||||
|
|
||||||
@ -110,22 +312,44 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Description: "The datastore id",
|
Description: "The datastore id",
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskDatastoreID,
|
Default: dvResourceVirtualEnvironmentVMDiskDatastoreID,
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMDiskEnabled: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Whether to enable the disk",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMDiskEnabled,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMDiskFileFormat: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The file format",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMDiskFileFormat,
|
||||||
|
ValidateFunc: getFileFormatValidator(),
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID: {
|
mkResourceVirtualEnvironmentVMDiskFileID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The file id for a disk image",
|
Description: "The file id for a disk image",
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskFileID,
|
Default: dvResourceVirtualEnvironmentVMDiskFileID,
|
||||||
|
ValidateFunc: getFileIDValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMDiskSize: {
|
mkResourceVirtualEnvironmentVMDiskSize: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The disk size in gigabytes",
|
Description: "The disk size in gigabytes",
|
||||||
Default: dvResourceVirtualEnvironmentVMDiskSize,
|
Default: dvResourceVirtualEnvironmentVMDiskSize,
|
||||||
|
ValidateFunc: validation.IntBetween(1, 8192),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxItems: 14,
|
MaxItems: 14,
|
||||||
MinItems: 1,
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMKeyboardLayout: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The keyboard layout",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMKeyboardLayout,
|
||||||
|
ValidateFunc: getKeyboardLayoutValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMMemory: &schema.Schema{
|
mkResourceVirtualEnvironmentVMMemory: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
@ -169,7 +393,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxItems: 1,
|
MaxItems: 1,
|
||||||
MinItems: 1,
|
MinItems: 0,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMName: {
|
mkResourceVirtualEnvironmentVMName: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
@ -182,17 +406,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Description: "The network devices",
|
Description: "The network devices",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
defaultList := make([]interface{}, 1)
|
return make([]interface{}, 1), nil
|
||||||
defaultMap := make(map[string]interface{})
|
|
||||||
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMNetworkDeviceBridge] = dvResourceVirtualEnvironmentVMNetworkDeviceBridge
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress] = dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMNetworkDeviceModel] = dvResourceVirtualEnvironmentVMNetworkDeviceModel
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMNetworkDeviceVLANID] = dvResourceVirtualEnvironmentVMNetworkDeviceVLANID
|
|
||||||
|
|
||||||
defaultList[0] = defaultMap
|
|
||||||
|
|
||||||
return defaultList, nil
|
|
||||||
},
|
},
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
@ -202,73 +416,57 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Description: "The bridge",
|
Description: "The bridge",
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Whether to enable the network device",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The MAC address",
|
Description: "The MAC address",
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
||||||
|
ValidateFunc: getMACAddressValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceModel: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The model",
|
Description: "The model",
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceModel,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceModel,
|
||||||
|
ValidateFunc: getNetworkDeviceModelValidator(),
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID: {
|
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The VLAN identifier",
|
Description: "The VLAN identifier",
|
||||||
Default: dvResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
Default: dvResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
||||||
ValidateFunc: func(i interface{}, k string) (s []string, es []error) {
|
ValidateFunc: getVLANIDValidator(),
|
||||||
min := 1
|
|
||||||
|
|
||||||
v, ok := i.(int)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
es = append(es, fmt.Errorf("expected type of %s to be int", k))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != -1 {
|
|
||||||
if v < min {
|
|
||||||
es = append(es, fmt.Errorf("expected %s to be at least %d, got %d", k, min, v))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxItems: 8,
|
MaxItems: 8,
|
||||||
MinItems: 0,
|
MinItems: 0,
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMNodeName: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The node name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMOSType: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The OS type",
|
||||||
|
Default: dvResourceVirtualEnvironmentVMOSType,
|
||||||
|
ValidateFunc: getOSTypeValidator(),
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMVMID: {
|
mkResourceVirtualEnvironmentVMVMID: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The identifier",
|
ForceNew: true,
|
||||||
|
Description: "The VM identifier",
|
||||||
Default: dvResourceVirtualEnvironmentVMVMID,
|
Default: dvResourceVirtualEnvironmentVMVMID,
|
||||||
ValidateFunc: func(i interface{}, k string) (s []string, es []error) {
|
ValidateFunc: getVMIDValidator(),
|
||||||
min := 100
|
|
||||||
max := 2000000
|
|
||||||
|
|
||||||
v, ok := i.(int)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
es = append(es, fmt.Errorf("expected type of %s to be int", k))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != -1 {
|
|
||||||
if v < min || v > max {
|
|
||||||
es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Create: resourceVirtualEnvironmentVMCreate,
|
Create: resourceVirtualEnvironmentVMCreate,
|
||||||
@ -279,7 +477,6 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) error {
|
func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) error {
|
||||||
/*
|
|
||||||
config := m.(providerConfiguration)
|
config := m.(providerConfiguration)
|
||||||
veClient, err := config.GetVEClient()
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
@ -287,8 +484,264 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId("")
|
schema := resourceVirtualEnvironmentVM().Schema
|
||||||
*/
|
cdrom := d.Get(mkResourceVirtualEnvironmentVMCDROM).([]interface{})
|
||||||
|
|
||||||
|
if len(cdrom) == 0 {
|
||||||
|
cdromDefault, err := schema[mkResourceVirtualEnvironmentVMCDROM].DefaultValue()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cdrom = cdromDefault.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
cdromBlock := cdrom[0].(map[string]interface{})
|
||||||
|
cdromEnabled := cdromBlock[mkResourceVirtualEnvironmentVMCDROMEnabled].(bool)
|
||||||
|
cdromFileID := cdromBlock[mkResourceVirtualEnvironmentVMCDROMFileID].(string)
|
||||||
|
|
||||||
|
if cdromFileID == "" {
|
||||||
|
cdromFileID = "cdrom"
|
||||||
|
}
|
||||||
|
|
||||||
|
var cloudInitConfig *proxmox.CustomCloudInitConfig
|
||||||
|
|
||||||
|
cloudInit := d.Get(mkResourceVirtualEnvironmentVMCloudInit).([]interface{})
|
||||||
|
|
||||||
|
if len(cloudInit) > 0 {
|
||||||
|
cdromEnabled = true
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
username := cloudInitUserAccountBlock[mkResourceVirtualEnvironmentVMCloudInitUserAccountUsername].(string)
|
||||||
|
|
||||||
|
cloudInitConfig.Username = &username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu := d.Get(mkResourceVirtualEnvironmentVMCPU).([]interface{})
|
||||||
|
|
||||||
|
if len(cpu) == 0 {
|
||||||
|
cpuDefault, err := schema[mkResourceVirtualEnvironmentVMCPU].DefaultValue()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu = cpuDefault.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuBlock := cpu[0].(map[string]interface{})
|
||||||
|
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
||||||
|
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
||||||
|
|
||||||
|
keyboardLayout := d.Get(mkResourceVirtualEnvironmentVMKeyboardLayout).(string)
|
||||||
|
memory := d.Get(mkResourceVirtualEnvironmentVMMemory).([]interface{})
|
||||||
|
|
||||||
|
if len(memory) == 0 {
|
||||||
|
memoryDefault, err := schema[mkResourceVirtualEnvironmentVMMemory].DefaultValue()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
memory = memoryDefault.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryBlock := memory[0].(map[string]interface{})
|
||||||
|
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentVMMemoryDedicated].(int)
|
||||||
|
memoryFloating := memoryBlock[mkResourceVirtualEnvironmentVMMemoryFloating].(int)
|
||||||
|
memoryShared := memoryBlock[mkResourceVirtualEnvironmentVMMemoryShared].(int)
|
||||||
|
|
||||||
|
name := d.Get(mkResourceVirtualEnvironmentVMName).(string)
|
||||||
|
|
||||||
|
networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{})
|
||||||
|
networkDeviceObjects := make(proxmox.CustomNetworkDevices, len(networkDevice))
|
||||||
|
|
||||||
|
for i, d := range networkDevice {
|
||||||
|
block := d.(map[string]interface{})
|
||||||
|
|
||||||
|
bridge, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceBridge].(string)
|
||||||
|
enabled, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceEnabled].(bool)
|
||||||
|
macAddress, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress].(string)
|
||||||
|
model, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceModel].(string)
|
||||||
|
vlanID, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceVLANID].(int)
|
||||||
|
|
||||||
|
device := proxmox.CustomNetworkDevice{
|
||||||
|
Enabled: enabled,
|
||||||
|
Model: model,
|
||||||
|
}
|
||||||
|
|
||||||
|
if bridge != "" {
|
||||||
|
device.Bridge = &bridge
|
||||||
|
}
|
||||||
|
|
||||||
|
if macAddress != "" {
|
||||||
|
device.MACAddress = &macAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
if vlanID != -1 {
|
||||||
|
device.Trunks = []int{vlanID}
|
||||||
|
}
|
||||||
|
|
||||||
|
networkDeviceObjects[i] = device
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string)
|
||||||
|
osType := d.Get(mkResourceVirtualEnvironmentVMOSType).(string)
|
||||||
|
vmID := d.Get(mkResourceVirtualEnvironmentVMVMID).(int)
|
||||||
|
|
||||||
|
if vmID == -1 {
|
||||||
|
vmIDNew, err := veClient.GetVMID()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
vmID = *vmIDNew
|
||||||
|
}
|
||||||
|
|
||||||
|
var memorySharedObject *proxmox.CustomSharedMemory
|
||||||
|
|
||||||
|
agentEnabled := proxmox.CustomBool(true)
|
||||||
|
bootOrder := "c"
|
||||||
|
|
||||||
|
if cdromEnabled {
|
||||||
|
bootOrder = "cd"
|
||||||
|
}
|
||||||
|
|
||||||
|
ideDevice2Media := "cdrom"
|
||||||
|
ideDevices := proxmox.CustomStorageDevices{
|
||||||
|
proxmox.CustomStorageDevice{
|
||||||
|
Enabled: false,
|
||||||
|
},
|
||||||
|
proxmox.CustomStorageDevice{
|
||||||
|
Enabled: false,
|
||||||
|
},
|
||||||
|
proxmox.CustomStorageDevice{
|
||||||
|
Enabled: cdromEnabled,
|
||||||
|
FileVolume: cdromFileID,
|
||||||
|
Media: &ideDevice2Media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if memoryShared > 0 {
|
||||||
|
memorySharedName := fmt.Sprintf("vm-%d-ivshmem", vmID)
|
||||||
|
memorySharedObject = &proxmox.CustomSharedMemory{
|
||||||
|
Name: &memorySharedName,
|
||||||
|
Size: memoryShared,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scsiHardware := "virtio-scsi-pci"
|
||||||
|
tabletDeviceEnabled := proxmox.CustomBool(true)
|
||||||
|
|
||||||
|
body := &proxmox.VirtualEnvironmentVMCreateRequestBody{
|
||||||
|
Agent: &proxmox.CustomAgent{Enabled: &agentEnabled},
|
||||||
|
BootOrder: &bootOrder,
|
||||||
|
CloudInitConfig: cloudInitConfig,
|
||||||
|
CPUCores: &cpuCores,
|
||||||
|
CPUSockets: &cpuSockets,
|
||||||
|
DedicatedMemory: &memoryDedicated,
|
||||||
|
FloatingMemory: &memoryFloating,
|
||||||
|
IDEDevices: ideDevices,
|
||||||
|
KeyboardLayout: &keyboardLayout,
|
||||||
|
NetworkDevices: networkDeviceObjects,
|
||||||
|
OSType: &osType,
|
||||||
|
SCSIHardware: &scsiHardware,
|
||||||
|
SerialDevices: []string{"socket"},
|
||||||
|
SharedMemory: memorySharedObject,
|
||||||
|
TabletDeviceEnabled: &tabletDeviceEnabled,
|
||||||
|
VGADevice: &proxmox.CustomVGADevice{Type: "serial0"},
|
||||||
|
VMID: &vmID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
body.Name = &name
|
||||||
|
}
|
||||||
|
|
||||||
|
err = veClient.CreateVM(nodeName, body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(strconv.Itoa(vmID))
|
||||||
|
|
||||||
return resourceVirtualEnvironmentVMRead(d, m)
|
return resourceVirtualEnvironmentVMRead(d, m)
|
||||||
}
|
}
|
||||||
@ -320,7 +773,6 @@ func resourceVirtualEnvironmentVMUpdate(d *schema.ResourceData, m interface{}) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceVirtualEnvironmentVMDelete(d *schema.ResourceData, m interface{}) error {
|
func resourceVirtualEnvironmentVMDelete(d *schema.ResourceData, m interface{}) error {
|
||||||
/*
|
|
||||||
config := m.(providerConfiguration)
|
config := m.(providerConfiguration)
|
||||||
veClient, err := config.GetVEClient()
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
@ -328,8 +780,26 @@ func resourceVirtualEnvironmentVMDelete(d *schema.ResourceData, m interface{}) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string)
|
||||||
|
vmID, err := strconv.Atoi(d.Id())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = veClient.DeleteVM(nodeName, vmID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "HTTP 404") {
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
*/
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -23,21 +23,31 @@ func TestResourceVirtualEnvironmentVMInstantiation(t *testing.T) {
|
|||||||
func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||||
s := resourceVirtualEnvironmentVM()
|
s := resourceVirtualEnvironmentVM()
|
||||||
|
|
||||||
|
testRequiredArguments(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentVMNodeName,
|
||||||
|
})
|
||||||
|
|
||||||
testOptionalArguments(t, s, []string{
|
testOptionalArguments(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROM,
|
||||||
mkResourceVirtualEnvironmentVMCPU,
|
mkResourceVirtualEnvironmentVMCPU,
|
||||||
mkResourceVirtualEnvironmentVMDisk,
|
mkResourceVirtualEnvironmentVMDisk,
|
||||||
|
mkResourceVirtualEnvironmentVMKeyboardLayout,
|
||||||
mkResourceVirtualEnvironmentVMMemory,
|
mkResourceVirtualEnvironmentVMMemory,
|
||||||
mkResourceVirtualEnvironmentVMName,
|
mkResourceVirtualEnvironmentVMName,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice,
|
mkResourceVirtualEnvironmentVMNetworkDevice,
|
||||||
|
mkResourceVirtualEnvironmentVMOSType,
|
||||||
mkResourceVirtualEnvironmentVMVMID,
|
mkResourceVirtualEnvironmentVMVMID,
|
||||||
})
|
})
|
||||||
|
|
||||||
testSchemaValueTypes(t, s, []string{
|
testSchemaValueTypes(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROM,
|
||||||
mkResourceVirtualEnvironmentVMCPU,
|
mkResourceVirtualEnvironmentVMCPU,
|
||||||
mkResourceVirtualEnvironmentVMDisk,
|
mkResourceVirtualEnvironmentVMDisk,
|
||||||
|
mkResourceVirtualEnvironmentVMKeyboardLayout,
|
||||||
mkResourceVirtualEnvironmentVMMemory,
|
mkResourceVirtualEnvironmentVMMemory,
|
||||||
mkResourceVirtualEnvironmentVMName,
|
mkResourceVirtualEnvironmentVMName,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice,
|
mkResourceVirtualEnvironmentVMNetworkDevice,
|
||||||
|
mkResourceVirtualEnvironmentVMOSType,
|
||||||
mkResourceVirtualEnvironmentVMVMID,
|
mkResourceVirtualEnvironmentVMVMID,
|
||||||
}, []schema.ValueType{
|
}, []schema.ValueType{
|
||||||
schema.TypeList,
|
schema.TypeList,
|
||||||
@ -45,9 +55,27 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
|||||||
schema.TypeList,
|
schema.TypeList,
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
schema.TypeList,
|
schema.TypeList,
|
||||||
|
schema.TypeString,
|
||||||
|
schema.TypeList,
|
||||||
|
schema.TypeString,
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
cdromSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCDROM)
|
||||||
|
|
||||||
|
testOptionalArguments(t, cdromSchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMEnabled,
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMFileID,
|
||||||
|
})
|
||||||
|
|
||||||
|
testSchemaValueTypes(t, cdromSchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMEnabled,
|
||||||
|
mkResourceVirtualEnvironmentVMCDROMFileID,
|
||||||
|
}, []schema.ValueType{
|
||||||
|
schema.TypeBool,
|
||||||
|
schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU)
|
cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU)
|
||||||
|
|
||||||
testOptionalArguments(t, cpuSchema, []string{
|
testOptionalArguments(t, cpuSchema, []string{
|
||||||
@ -67,15 +95,21 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
|||||||
|
|
||||||
testOptionalArguments(t, diskSchema, []string{
|
testOptionalArguments(t, diskSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID,
|
mkResourceVirtualEnvironmentVMDiskDatastoreID,
|
||||||
|
mkResourceVirtualEnvironmentVMDiskEnabled,
|
||||||
|
mkResourceVirtualEnvironmentVMDiskFileFormat,
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID,
|
mkResourceVirtualEnvironmentVMDiskFileID,
|
||||||
mkResourceVirtualEnvironmentVMDiskSize,
|
mkResourceVirtualEnvironmentVMDiskSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
testSchemaValueTypes(t, diskSchema, []string{
|
testSchemaValueTypes(t, diskSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID,
|
mkResourceVirtualEnvironmentVMDiskDatastoreID,
|
||||||
|
mkResourceVirtualEnvironmentVMDiskEnabled,
|
||||||
|
mkResourceVirtualEnvironmentVMDiskFileFormat,
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID,
|
mkResourceVirtualEnvironmentVMDiskFileID,
|
||||||
mkResourceVirtualEnvironmentVMDiskSize,
|
mkResourceVirtualEnvironmentVMDiskSize,
|
||||||
}, []schema.ValueType{
|
}, []schema.ValueType{
|
||||||
|
schema.TypeString,
|
||||||
|
schema.TypeBool,
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
@ -103,6 +137,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
|||||||
|
|
||||||
testOptionalArguments(t, networkDeviceSchema, []string{
|
testOptionalArguments(t, networkDeviceSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
mkResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
||||||
|
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel,
|
mkResourceVirtualEnvironmentVMNetworkDeviceModel,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
||||||
@ -110,11 +145,13 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
|||||||
|
|
||||||
testSchemaValueTypes(t, networkDeviceSchema, []string{
|
testSchemaValueTypes(t, networkDeviceSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
mkResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
||||||
|
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel,
|
mkResourceVirtualEnvironmentVMNetworkDeviceModel,
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
||||||
}, []schema.ValueType{
|
}, []schema.ValueType{
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
|
schema.TypeBool,
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
schema.TypeString,
|
schema.TypeString,
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
|
@ -5,11 +5,161 @@
|
|||||||
package proxmoxtf
|
package proxmoxtf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getFileFormatValidator() schema.SchemaValidateFunc {
|
||||||
|
return validation.StringInSlice([]string{"qcow2", "raw", "vmdk"}, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFileIDValidator() schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (ws []string, es []error) {
|
||||||
|
v, ok := i.(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be string", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != "" {
|
||||||
|
r := regexp.MustCompile(`^(?i)[a-z0-9\-_]+:([a-z0-9\-_]+/)?.+$`)
|
||||||
|
ok := r.MatchString(v)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected %s to be a valid file identifier (datastore-name:iso/some-file.img), got %s", k, v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKeyboardLayoutValidator() schema.SchemaValidateFunc {
|
||||||
|
return validation.StringInSlice([]string{
|
||||||
|
"da",
|
||||||
|
"de",
|
||||||
|
"de-ch",
|
||||||
|
"en-gb",
|
||||||
|
"en-us",
|
||||||
|
"es",
|
||||||
|
"fi",
|
||||||
|
"fr",
|
||||||
|
"fr-be",
|
||||||
|
"fr-ca",
|
||||||
|
"fr-ch",
|
||||||
|
"hu",
|
||||||
|
"is",
|
||||||
|
"it",
|
||||||
|
"ja",
|
||||||
|
"lt",
|
||||||
|
"mk",
|
||||||
|
"nl",
|
||||||
|
"no",
|
||||||
|
"pl",
|
||||||
|
"pt",
|
||||||
|
"pt-br",
|
||||||
|
"sl",
|
||||||
|
"sv",
|
||||||
|
"tr",
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMACAddressValidator() schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (ws []string, es []error) {
|
||||||
|
v, ok := i.(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be string", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != "" {
|
||||||
|
r := regexp.MustCompile(`^[A-Z0-9]{2}(:[A-Z0-9]{2}){5}$`)
|
||||||
|
ok := r.MatchString(v)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected %s to be a valid MAC address (A0:B1:C2:D3:E4:F5), got %s", k, v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNetworkDeviceModelValidator() schema.SchemaValidateFunc {
|
||||||
|
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 getVLANIDValidator() schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (ws []string, es []error) {
|
||||||
|
min := 1
|
||||||
|
max := 4094
|
||||||
|
|
||||||
|
v, ok := i.(int)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be int", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != -1 {
|
||||||
|
if v < min || v > max {
|
||||||
|
es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVMIDValidator() schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (ws []string, es []error) {
|
||||||
|
min := 1
|
||||||
|
max := 2147483647
|
||||||
|
|
||||||
|
v, ok := i.(int)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be int", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != -1 {
|
||||||
|
if v < min || v > max {
|
||||||
|
es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) {
|
func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) {
|
||||||
for _, v := range keys {
|
for _, v := range keys {
|
||||||
if s.Schema[v] == nil {
|
if s.Schema[v] == nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user