0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00
terraform-provider-proxmox/proxmoxtf/resource/vm/network/network.go
Pavel Boldyrev 29b5438faf
chore(vm): refactoring: extract network device code from vm.go (#1127)
chore(vm): refactoring: extract network code

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2024-03-16 01:06:30 +00:00

277 lines
7.3 KiB
Go

package network
import (
"context"
"fmt"
"strconv"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// GetNetworkDeviceObjects returns a list of network devices from the resource data.
func GetNetworkDeviceObjects(d *schema.ResourceData) (vms.CustomNetworkDevices, error) {
networkDevice := d.Get(MkNetworkDevice).([]interface{})
networkDeviceObjects := make(vms.CustomNetworkDevices, len(networkDevice))
for i, networkDeviceEntry := range networkDevice {
block := networkDeviceEntry.(map[string]interface{})
bridge := block[mkNetworkDeviceBridge].(string)
enabled := block[mkNetworkDeviceEnabled].(bool)
firewall := types.CustomBool(block[mkNetworkDeviceFirewall].(bool))
macAddress := block[mkNetworkDeviceMACAddress].(string)
model := block[mkNetworkDeviceModel].(string)
queues := block[mkNetworkDeviceQueues].(int)
rateLimit := block[mkNetworkDeviceRateLimit].(float64)
vlanID := block[mkNetworkDeviceVLANID].(int)
trunks := block[mkNetworkDeviceTrunks].(string)
mtu := block[mkNetworkDeviceMTU].(int)
device := vms.CustomNetworkDevice{
Enabled: enabled,
Firewall: &firewall,
Model: model,
}
if bridge != "" {
device.Bridge = &bridge
}
if macAddress != "" {
device.MACAddress = &macAddress
}
if queues != 0 {
device.Queues = &queues
}
if rateLimit != 0 {
device.RateLimit = &rateLimit
}
if vlanID != 0 {
device.Tag = &vlanID
}
if trunks != "" {
splitTrunks := strings.Split(trunks, ";")
var trunksAsInt []int
for _, numStr := range splitTrunks {
num, err := strconv.Atoi(numStr)
if err != nil {
return nil, fmt.Errorf("error parsing trunks: %w", err)
}
trunksAsInt = append(trunksAsInt, num)
}
device.Trunks = trunksAsInt
}
if mtu != 0 {
device.MTU = &mtu
}
networkDeviceObjects[i] = device
}
return networkDeviceObjects, nil
}
// ReadNetworkDeviceObjects reads the network device objects from the resource data.
func ReadNetworkDeviceObjects(d *schema.ResourceData, vmConfig *vms.GetResponseData) diag.Diagnostics {
var diags diag.Diagnostics
// Compare the network devices to those stored in the state.
currentNetworkDeviceList := d.Get(MkNetworkDevice).([]interface{})
macAddresses := make([]interface{}, MaxNetworkDevices)
networkDeviceLast := -1
networkDeviceList := make([]interface{}, MaxNetworkDevices)
networkDeviceObjects := []*vms.CustomNetworkDevice{
vmConfig.NetworkDevice0,
vmConfig.NetworkDevice1,
vmConfig.NetworkDevice2,
vmConfig.NetworkDevice3,
vmConfig.NetworkDevice4,
vmConfig.NetworkDevice5,
vmConfig.NetworkDevice6,
vmConfig.NetworkDevice7,
vmConfig.NetworkDevice8,
vmConfig.NetworkDevice9,
vmConfig.NetworkDevice10,
vmConfig.NetworkDevice11,
vmConfig.NetworkDevice12,
vmConfig.NetworkDevice13,
vmConfig.NetworkDevice14,
vmConfig.NetworkDevice15,
vmConfig.NetworkDevice16,
vmConfig.NetworkDevice17,
vmConfig.NetworkDevice18,
vmConfig.NetworkDevice19,
vmConfig.NetworkDevice20,
vmConfig.NetworkDevice21,
vmConfig.NetworkDevice22,
vmConfig.NetworkDevice23,
vmConfig.NetworkDevice24,
vmConfig.NetworkDevice25,
vmConfig.NetworkDevice26,
vmConfig.NetworkDevice27,
vmConfig.NetworkDevice28,
vmConfig.NetworkDevice29,
vmConfig.NetworkDevice30,
vmConfig.NetworkDevice31,
}
for ni, nd := range networkDeviceObjects {
networkDevice := map[string]interface{}{}
if nd != nil {
networkDeviceLast = ni
if nd.Bridge != nil {
networkDevice[mkNetworkDeviceBridge] = *nd.Bridge
} else {
networkDevice[mkNetworkDeviceBridge] = ""
}
networkDevice[mkNetworkDeviceEnabled] = nd.Enabled
if nd.Firewall != nil {
networkDevice[mkNetworkDeviceFirewall] = *nd.Firewall
} else {
networkDevice[mkNetworkDeviceFirewall] = false
}
if nd.MACAddress != nil {
macAddresses[ni] = *nd.MACAddress
} else {
macAddresses[ni] = ""
}
networkDevice[mkNetworkDeviceMACAddress] = macAddresses[ni]
networkDevice[mkNetworkDeviceModel] = nd.Model
if nd.Queues != nil {
networkDevice[mkNetworkDeviceQueues] = *nd.Queues
} else {
networkDevice[mkNetworkDeviceQueues] = 0
}
if nd.RateLimit != nil {
networkDevice[mkNetworkDeviceRateLimit] = *nd.RateLimit
} else {
networkDevice[mkNetworkDeviceRateLimit] = 0
}
if nd.Tag != nil {
networkDevice[mkNetworkDeviceVLANID] = nd.Tag
} else {
networkDevice[mkNetworkDeviceVLANID] = 0
}
if nd.Trunks != nil {
networkDevice[mkNetworkDeviceTrunks] = strings.Trim(
strings.Join(strings.Fields(fmt.Sprint(nd.Trunks)), ";"), "[]")
} else {
networkDevice[mkNetworkDeviceTrunks] = ""
}
if nd.MTU != nil {
networkDevice[mkNetworkDeviceMTU] = nd.MTU
} else {
networkDevice[mkNetworkDeviceMTU] = 0
}
} else {
macAddresses[ni] = ""
networkDevice[mkNetworkDeviceEnabled] = false
}
networkDeviceList[ni] = networkDevice
}
if len(currentNetworkDeviceList) > 0 || networkDeviceLast > -1 {
err := d.Set(MkNetworkDevice, networkDeviceList[:networkDeviceLast+1])
diags = append(diags, diag.FromErr(err)...)
}
err := d.Set(mkMACAddresses, macAddresses[0:len(currentNetworkDeviceList)])
diags = append(diags, diag.FromErr(err)...)
return diags
}
// ReadNetworkValues reads the network values from the resource data.
func ReadNetworkValues(
ctx context.Context,
d *schema.ResourceData,
vmAPI *vms.Client,
started bool,
vmConfig *vms.GetResponseData,
agentTimeout time.Duration,
) diag.Diagnostics {
var diags diag.Diagnostics
var ipv4Addresses []interface{}
var ipv6Addresses []interface{}
var networkInterfaceNames []interface{}
if started {
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
var macAddresses []interface{}
networkInterfaces, err := vmAPI.WaitForNetworkInterfacesFromVMAgent(ctx, int(agentTimeout.Seconds()), 5, true)
if err == nil && networkInterfaces.Result != nil {
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
ipv6Addresses = make([]interface{}, len(*networkInterfaces.Result))
macAddresses = make([]interface{}, len(*networkInterfaces.Result))
networkInterfaceNames = make([]interface{}, len(*networkInterfaces.Result))
for ri, rv := range *networkInterfaces.Result {
var rvIPv4Addresses []interface{}
var rvIPv6Addresses []interface{}
if rv.IPAddresses != nil {
for _, ip := range *rv.IPAddresses {
switch ip.Type {
case "ipv4":
rvIPv4Addresses = append(rvIPv4Addresses, ip.Address)
case "ipv6":
rvIPv6Addresses = append(rvIPv6Addresses, ip.Address)
}
}
}
ipv4Addresses[ri] = rvIPv4Addresses
ipv6Addresses[ri] = rvIPv6Addresses
macAddresses[ri] = strings.ToUpper(rv.MACAddress)
networkInterfaceNames[ri] = rv.Name
}
}
err = d.Set(mkMACAddresses, macAddresses)
diags = append(diags, diag.FromErr(err)...)
}
}
e := d.Set(mkIPv4Addresses, ipv4Addresses)
diags = append(diags, diag.FromErr(e)...)
e = d.Set(mkIPv6Addresses, ipv6Addresses)
diags = append(diags, diag.FromErr(e)...)
e = d.Set(mkNetworkInterfaceNames, networkInterfaceNames)
diags = append(diags, diag.FromErr(e)...)
return diags
}