diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index 57e38e7b..a2d2e53b 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -408,20 +408,17 @@ output "ubuntu_vm_public_key" { it (defaults to `false`). - `name` - (Optional) The virtual machine name. - `network_device` - (Optional) A network device (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`). - - `firewall` - (Optional) Whether this interface's firewall rules should be - used (defaults to `false`). + - `bridge` - (Optional) The name of the network bridge (defaults to `vmbr0`). + - `disconnected` - (Optional) Whether to disconnect the network device from the network (defaults to `false`). + - `enabled` - (Optional) Whether to enable the network device (defaults to `true`). + - `firewall` - (Optional) Whether this interface's firewall rules should be used (defaults to `false`). - `mac_address` - (Optional) The MAC address. - `model` - (Optional) The network device model (defaults to `virtio`). - `e1000` - Intel E1000. - `rtl8139` - Realtek RTL8139. - `virtio` - VirtIO (paravirtualized). - `vmxnet3` - VMware vmxnet3. - - `mtu` - (Optional) Force MTU, for VirtIO only. Set to 1 to use the bridge - MTU. Cannot be larger than the bridge MTU. + - `mtu` - (Optional) Force MTU, for VirtIO only. Set to 1 to use the bridge MTU. Cannot be larger than the bridge MTU. - `queues` - (Optional) The number of queues for VirtIO (1..64). - `rate_limit` - (Optional) The rate limit in megabytes per second. - `vlan_id` - (Optional) The VLAN identifier. diff --git a/fwprovider/tests/resource_vm_test.go b/fwprovider/tests/resource_vm_test.go index e13305b6..116b4bba 100644 --- a/fwprovider/tests/resource_vm_test.go +++ b/fwprovider/tests/resource_vm_test.go @@ -109,9 +109,9 @@ func TestAccResourceVMNetwork(t *testing.T) { tests := []struct { name string - step resource.TestStep + step []resource.TestStep }{ - {"network interfaces", resource.TestStep{ + {"network interfaces", []resource.TestStep{{ Config: providerConfig + ` resource "proxmox_virtual_environment_file" "cloud_config" { content_type = "snippets" @@ -179,7 +179,41 @@ EOF "network_device.0.trunks": "10;20;30", }), ), - }}, + }}}, + {"network device disconnected", []resource.TestStep{{ + Config: ` + resource "proxmox_virtual_environment_vm" "test_vm_network2" { + node_name = "pve" + started = false + + network_device { + bridge = "vmbr0" + } + }`, + Check: resource.ComposeTestCheckFunc( + testResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{ + "network_device.0.bridge": "vmbr0", + "network_device.0.disconnected": "false", + }), + ), + }, { + Config: ` + resource "proxmox_virtual_environment_vm" "test_vm_network2" { + node_name = "pve" + started = false + + network_device { + bridge = "vmbr0" + disconnected = true + } + }`, + Check: resource.ComposeTestCheckFunc( + testResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{ + "network_device.0.bridge": "vmbr0", + "network_device.0.disconnected": "true", + }), + ), + }}}, } accProviders := testAccMuxProviders(context.Background(), t) @@ -191,7 +225,7 @@ EOF resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: accProviders, - Steps: []resource.TestStep{tt.step}, + Steps: tt.step, }) }) } diff --git a/proxmox/nodes/vms/vms_types.go b/proxmox/nodes/vms/vms_types.go index 4791e7c5..10086d94 100644 --- a/proxmox/nodes/vms/vms_types.go +++ b/proxmox/nodes/vms/vms_types.go @@ -89,16 +89,16 @@ type CustomEFIDisk struct { // CustomNetworkDevice handles QEMU network device parameters. type CustomNetworkDevice struct { - Model string `json:"model" url:"model"` - Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"` Enabled bool `json:"-" url:"-"` + Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"` Firewall *types.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"` LinkDown *types.CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"` MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"` + MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"` + Model string `json:"model" url:"model"` Queues *int `json:"queues,omitempty" url:"queues,omitempty"` RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"` Tag *int `json:"tag,omitempty" url:"tag,omitempty"` - MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"` Trunks []int `json:"trunks,omitempty" url:"trunks,omitempty"` } diff --git a/proxmoxtf/resource/vm/network/network.go b/proxmoxtf/resource/vm/network/network.go index 8ee94bba..22ecf685 100644 --- a/proxmoxtf/resource/vm/network/network.go +++ b/proxmoxtf/resource/vm/network/network.go @@ -23,15 +23,16 @@ func GetNetworkDeviceObjects(d *schema.ResourceData) (vms.CustomNetworkDevices, block := networkDeviceEntry.(map[string]interface{}) bridge := block[mkNetworkDeviceBridge].(string) + disconnected := types.CustomBool(block[mkNetworkDeviceDisconnected].(bool)) enabled := block[mkNetworkDeviceEnabled].(bool) firewall := types.CustomBool(block[mkNetworkDeviceFirewall].(bool)) macAddress := block[mkNetworkDeviceMACAddress].(string) model := block[mkNetworkDeviceModel].(string) + mtu := block[mkNetworkDeviceMTU].(int) queues := block[mkNetworkDeviceQueues].(int) rateLimit := block[mkNetworkDeviceRateLimit].(float64) - vlanID := block[mkNetworkDeviceVLANID].(int) trunks := block[mkNetworkDeviceTrunks].(string) - mtu := block[mkNetworkDeviceMTU].(int) + vlanID := block[mkNetworkDeviceVLANID].(int) device := vms.CustomNetworkDevice{ Enabled: enabled, @@ -43,6 +44,10 @@ func GetNetworkDeviceObjects(d *schema.ResourceData) (vms.CustomNetworkDevices, device.Bridge = &bridge } + if disconnected { + device.LinkDown = &disconnected + } + if macAddress != "" { device.MACAddress = &macAddress } @@ -145,6 +150,12 @@ func ReadNetworkDeviceObjects(d *schema.ResourceData, vmConfig *vms.GetResponseD networkDevice[mkNetworkDeviceEnabled] = nd.Enabled + if nd.LinkDown != nil { + networkDevice[mkNetworkDeviceDisconnected] = *nd.LinkDown + } else { + networkDevice[mkNetworkDeviceDisconnected] = false + } + if nd.Firewall != nil { networkDevice[mkNetworkDeviceFirewall] = *nd.Firewall } else { diff --git a/proxmoxtf/resource/vm/network/schema.go b/proxmoxtf/resource/vm/network/schema.go index 5a1515a7..d9173b8c 100644 --- a/proxmoxtf/resource/vm/network/schema.go +++ b/proxmoxtf/resource/vm/network/schema.go @@ -17,30 +17,31 @@ const ( dvNetworkDeviceBridge = "vmbr0" dvNetworkDeviceEnabled = true dvNetworkDeviceFirewall = false + dvNetworkDeviceMTU = 0 dvNetworkDeviceModel = "virtio" dvNetworkDeviceQueues = 0 dvNetworkDeviceRateLimit = 0 - dvNetworkDeviceVLANID = 0 dvNetworkDeviceTrunks = "" - dvNetworkDeviceMTU = 0 + dvNetworkDeviceVLANID = 0 mkIPv4Addresses = "ipv4_addresses" mkIPv6Addresses = "ipv6_addresses" mkMACAddresses = "mac_addresses" // MkNetworkDevice is the name of the network device. - MkNetworkDevice = "network_device" - mkNetworkDeviceBridge = "bridge" - mkNetworkDeviceEnabled = "enabled" - mkNetworkDeviceFirewall = "firewall" - mkNetworkDeviceMACAddress = "mac_address" - mkNetworkDeviceModel = "model" - mkNetworkDeviceQueues = "queues" - mkNetworkDeviceRateLimit = "rate_limit" - mkNetworkDeviceVLANID = "vlan_id" - mkNetworkDeviceTrunks = "trunks" - mkNetworkDeviceMTU = "mtu" - mkNetworkInterfaceNames = "network_interface_names" + MkNetworkDevice = "network_device" + mkNetworkDeviceBridge = "bridge" + mkNetworkDeviceDisconnected = "disconnected" + mkNetworkDeviceEnabled = "enabled" + mkNetworkDeviceFirewall = "firewall" + mkNetworkDeviceMACAddress = "mac_address" + mkNetworkDeviceMTU = "mtu" + mkNetworkDeviceModel = "model" + mkNetworkDeviceQueues = "queues" + mkNetworkDeviceRateLimit = "rate_limit" + mkNetworkDeviceTrunks = "trunks" + mkNetworkDeviceVLANID = "vlan_id" + mkNetworkInterfaceNames = "network_interface_names" ) // Schema returns the schema for the network resource. @@ -86,6 +87,11 @@ func Schema() map[string]*schema.Schema { Optional: true, Default: dvNetworkDeviceBridge, }, + mkNetworkDeviceDisconnected: { + Type: schema.TypeBool, + Description: "Whether the network device should be disconnected from the network", + Optional: true, + }, mkNetworkDeviceEnabled: { Type: schema.TypeBool, Description: "Whether to enable the network device",