diff --git a/docs/resources/virtual_environment_container.md b/docs/resources/virtual_environment_container.md index d4fee1550..9d633f632 100644 --- a/docs/resources/virtual_environment_container.md +++ b/docs/resources/virtual_environment_container.md @@ -127,6 +127,7 @@ output "ubuntu_container_public_key" { * `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. + * `mtu` - (Optional) Maximum transfer unit of the interface. Cannot be larger than the bridge's MTU. * `name` - (Required) The network interface name. * `rate_limit` - (Optional) The rate limit in megabytes per second. * `vlan_id` - (Optional) The VLAN identifier. diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index a7ccfd4e4..16c4d868e 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -259,6 +259,7 @@ output "ubuntu_vm_public_key" { * `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. * `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 virtual machine to. diff --git a/example/resource_virtual_environment_container.tf b/example/resource_virtual_environment_container.tf index 3f8873990..88e584813 100644 --- a/example/resource_virtual_environment_container.tf +++ b/example/resource_virtual_environment_container.tf @@ -26,6 +26,7 @@ resource "proxmox_virtual_environment_container" "example_template" { network_interface { name = "veth0" + mtu = 1450 } node_name = data.proxmox_virtual_environment_nodes.example.names[0] diff --git a/example/resource_virtual_environment_vm.tf b/example/resource_virtual_environment_vm.tf index 6e6cc4f97..670170c03 100644 --- a/example/resource_virtual_environment_vm.tf +++ b/example/resource_virtual_environment_vm.tf @@ -50,7 +50,9 @@ resource "proxmox_virtual_environment_vm" "example_template" { name = "terraform-provider-proxmox-example-template" - network_device {} + network_device { + mtu = 1450 + } network_device { vlan_id = 1024 diff --git a/proxmox/virtual_environment_vm_types.go b/proxmox/virtual_environment_vm_types.go index 5b4311067..656f1de50 100644 --- a/proxmox/virtual_environment_vm_types.go +++ b/proxmox/virtual_environment_vm_types.go @@ -88,6 +88,7 @@ type CustomNetworkDevice struct { 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"` } @@ -802,6 +803,9 @@ func (r CustomNetworkDevice) EncodeValues(key string, v *url.Values) error { if r.Tag != nil { values = append(values, fmt.Sprintf("tag=%d", *r.Tag)) } + if r.MTU != nil { + values = append(values, fmt.Sprintf("mtu=%d", *r.MTU)) + } if len(r.Trunks) > 0 { trunks := make([]string, len(r.Trunks)) @@ -1462,6 +1466,14 @@ func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error { } r.RateLimit = &fv + case "mtu": + iv, err := strconv.Atoi(v[1]) + + if err != nil { + return err + } + r.MTU = &iv + case "tag": iv, err := strconv.Atoi(v[1]) diff --git a/proxmoxtf/resource_virtual_environment_container.go b/proxmoxtf/resource_virtual_environment_container.go index d33a392a6..5e65a1132 100644 --- a/proxmoxtf/resource_virtual_environment_container.go +++ b/proxmoxtf/resource_virtual_environment_container.go @@ -7,10 +7,11 @@ package proxmoxtf import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "strconv" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -42,6 +43,7 @@ const ( dvResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress = "" dvResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit = 0 dvResourceVirtualEnvironmentContainerNetworkInterfaceVLANID = 0 + dvResourceVirtualEnvironmentContainerNetworkInterfaceMTU = 0 dvResourceVirtualEnvironmentContainerOperatingSystemType = "unmanaged" dvResourceVirtualEnvironmentContainerPoolID = "" dvResourceVirtualEnvironmentContainerStarted = true @@ -91,6 +93,7 @@ const ( mkResourceVirtualEnvironmentContainerNetworkInterfaceName = "name" mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit = "rate_limit" mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID = "vlan_id" + mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU = "mtu" mkResourceVirtualEnvironmentContainerNodeName = "node_name" mkResourceVirtualEnvironmentContainerOperatingSystem = "operating_system" mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID = "template_file_id" @@ -481,6 +484,12 @@ func resourceVirtualEnvironmentContainer() *schema.Resource { Optional: true, Default: dvResourceVirtualEnvironmentContainerNetworkInterfaceVLANID, }, + mkResourceVirtualEnvironmentVMNetworkDeviceMTU: { + Type: schema.TypeInt, + Description: "Maximum transmission unit (MTU)", + Optional: true, + Default: dvResourceVirtualEnvironmentVMNetworkDeviceMTU, + }, }, }, MaxItems: maxResourceVirtualEnvironmentContainerNetworkInterfaces, @@ -791,6 +800,7 @@ func resourceVirtualEnvironmentContainerCreateClone(ctx context.Context, d *sche name := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceName].(string) rateLimit := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit].(float64) vlanID := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID].(int) + mtu, _ := networkInterfaceMap[mkResourceVirtualEnvironmentVMNetworkDeviceMTU].(int) if bridge != "" { networkInterfaceObject.Bridge = &bridge @@ -830,6 +840,10 @@ func resourceVirtualEnvironmentContainerCreateClone(ctx context.Context, d *sche networkInterfaceObject.Tag = &vlanID } + if mtu != 0 { + networkInterfaceObject.MTU = &mtu + } + networkInterfaceArray[ni] = networkInterfaceObject } @@ -1003,6 +1017,7 @@ func resourceVirtualEnvironmentContainerCreateCustom(ctx context.Context, d *sch name := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceName].(string) rateLimit := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit].(float64) vlanID := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID].(int) + mtu := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU].(int) if bridge != "" { networkInterfaceObject.Bridge = &bridge @@ -1041,6 +1056,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(ctx context.Context, d *sch if vlanID != 0 { networkInterfaceObject.Tag = &vlanID } + if mtu != 0 { + networkInterfaceObject.MTU = &mtu + } networkInterfaceArray[ni] = networkInterfaceObject } @@ -1237,6 +1255,12 @@ func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx context. networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID] = 0 } + if nv.MTU != nil { + networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU] = *nv.MTU + } else { + networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU] = 0 + } + networkInterfaces = append(networkInterfaces, networkInterface) } @@ -1552,6 +1576,12 @@ func resourceVirtualEnvironmentContainerRead(ctx context.Context, d *schema.Reso networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID] = 0 } + if nv.MTU != nil { + networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU] = *nv.MTU + } else { + networkInterface[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU] = 0 + } + networkInterfaceList = append(networkInterfaceList, networkInterface) } @@ -1833,6 +1863,7 @@ func resourceVirtualEnvironmentContainerUpdate(ctx context.Context, d *schema.Re name := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceName].(string) rateLimit := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit].(float64) vlanID := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID].(int) + mtu := networkInterfaceMap[mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU].(int) if bridge != "" { networkInterfaceObject.Bridge = &bridge @@ -1872,6 +1903,10 @@ func resourceVirtualEnvironmentContainerUpdate(ctx context.Context, d *schema.Re networkInterfaceObject.Tag = &vlanID } + if mtu != 0 { + networkInterfaceObject.MTU = &mtu + } + networkInterfaceArray[ni] = networkInterfaceObject } diff --git a/proxmoxtf/resource_virtual_environment_container_test.go b/proxmoxtf/resource_virtual_environment_container_test.go index 6350fcb31..1f9c21b86 100644 --- a/proxmoxtf/resource_virtual_environment_container_test.go +++ b/proxmoxtf/resource_virtual_environment_container_test.go @@ -194,6 +194,7 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress, mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit, mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID, + mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU, }) testValueTypes(t, networkInterfaceSchema, map[string]schema.ValueType{ @@ -203,6 +204,7 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerNetworkInterfaceName: schema.TypeString, mkResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit: schema.TypeFloat, mkResourceVirtualEnvironmentContainerNetworkInterfaceVLANID: schema.TypeInt, + mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU: schema.TypeInt, }) operatingSystemSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerOperatingSystem) diff --git a/proxmoxtf/resource_virtual_environment_vm.go b/proxmoxtf/resource_virtual_environment_vm.go index 2408c09d8..681287cb4 100644 --- a/proxmoxtf/resource_virtual_environment_vm.go +++ b/proxmoxtf/resource_virtual_environment_vm.go @@ -80,6 +80,7 @@ const ( dvResourceVirtualEnvironmentVMNetworkDeviceModel = "virtio" dvResourceVirtualEnvironmentVMNetworkDeviceRateLimit = 0 dvResourceVirtualEnvironmentVMNetworkDeviceVLANID = 0 + dvResourceVirtualEnvironmentVMNetworkDeviceMTU = 0 dvResourceVirtualEnvironmentVMOperatingSystemType = "other" dvResourceVirtualEnvironmentVMPoolID = "" dvResourceVirtualEnvironmentVMSerialDeviceDevice = "socket" @@ -181,6 +182,7 @@ const ( mkResourceVirtualEnvironmentVMNetworkDeviceModel = "model" mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit = "rate_limit" mkResourceVirtualEnvironmentVMNetworkDeviceVLANID = "vlan_id" + mkResourceVirtualEnvironmentVMNetworkDeviceMTU = "mtu" mkResourceVirtualEnvironmentVMNetworkInterfaceNames = "network_interface_names" mkResourceVirtualEnvironmentVMNodeName = "node_name" mkResourceVirtualEnvironmentVMOperatingSystem = "operating_system" @@ -903,6 +905,12 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Optional: true, Default: dvResourceVirtualEnvironmentVMNetworkDeviceVLANID, }, + mkResourceVirtualEnvironmentVMNetworkDeviceMTU: { + Type: schema.TypeInt, + Description: "Maximum transmission unit (MTU)", + Optional: true, + Default: dvResourceVirtualEnvironmentVMNetworkDeviceMTU, + }, }, }, MaxItems: maxResourceVirtualEnvironmentVMNetworkDevices, @@ -2324,6 +2332,7 @@ func resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d *schema.ResourceData) model, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceModel].(string) rateLimit, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit].(float64) vlanID, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceVLANID].(int) + mtu, _ := block[mkResourceVirtualEnvironmentVMNetworkDeviceMTU].(int) device := proxmox.CustomNetworkDevice{ Enabled: enabled, @@ -2346,6 +2355,10 @@ func resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d *schema.ResourceData) device.Tag = &vlanID } + if mtu != 0 { + device.MTU = &mtu + } + networkDeviceObjects[i] = device } @@ -3080,6 +3093,11 @@ func resourceVirtualEnvironmentVMReadCustom(ctx context.Context, d *schema.Resou } else { networkDevice[mkResourceVirtualEnvironmentVMNetworkDeviceVLANID] = 0 } + if nd.MTU != nil { + networkDevice[mkResourceVirtualEnvironmentVMNetworkDeviceMTU] = nd.MTU + } else { + networkDevice[mkResourceVirtualEnvironmentVMNetworkDeviceMTU] = 0 + } } else { macAddresses[ni] = "" networkDevice[mkResourceVirtualEnvironmentVMNetworkDeviceEnabled] = false diff --git a/proxmoxtf/resource_virtual_environment_vm_test.go b/proxmoxtf/resource_virtual_environment_vm_test.go index a4e95818c..57df15d69 100644 --- a/proxmoxtf/resource_virtual_environment_vm_test.go +++ b/proxmoxtf/resource_virtual_environment_vm_test.go @@ -296,6 +296,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMNetworkDeviceModel, mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit, mkResourceVirtualEnvironmentVMNetworkDeviceVLANID, + mkResourceVirtualEnvironmentVMNetworkDeviceMTU, }) testValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{ @@ -305,6 +306,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMNetworkDeviceModel: schema.TypeString, mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit: schema.TypeFloat, mkResourceVirtualEnvironmentVMNetworkDeviceVLANID: schema.TypeInt, + mkResourceVirtualEnvironmentVMNetworkDeviceMTU: schema.TypeInt, }) operatingSystemSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMOperatingSystem)