0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

fix(lxc): spurious ip_config diff when interface has both IPv4 and IPv6 addresses

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2025-05-05 20:57:02 -04:00
parent 922d1ebd8a
commit 15b0ae90be
No known key found for this signature in database
GPG Key ID: 637146A2A6804C59
2 changed files with 52 additions and 19 deletions

View File

@ -255,6 +255,45 @@ func TestAccResourceContainer(t *testing.T) {
}), }),
}, },
}}, }},
{"ipv4 and ipv6", []resource.TestStep{{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_container" "test_container" {
node_name = "{{.NodeName}}"
started = false
disk {
datastore_id = "local-lvm"
size = 4
}
initialization {
hostname = "test"
ip_config {
ipv4 {
address = "10.0.0.100/24"
gateway = "10.0.0.1"
}
}
ip_config {
ipv6 {
address = "2001:db8::100/64"
gateway = "2001:db8::1"
}
}
}
network_interface {
name = "vmbr0"
bridge = "vmbr0"
}
network_interface {
name = "vmbr1"
bridge = "vmbr1"
}
operating_system {
template_file_id = "local:vztmpl/{{.ImageFileName}}"
type = "ubuntu"
}
}`),
}}},
{"clone container", []resource.TestStep{{ {"clone container", []resource.TestStep{{
Config: te.RenderConfig(` Config: te.RenderConfig(`
resource "proxmox_virtual_environment_container" "test_container" { resource "proxmox_virtual_environment_container" "test_container" {

View File

@ -1934,6 +1934,7 @@ func containerCreateStart(ctx context.Context, d *schema.ResourceData, m interfa
return containerRead(ctx, d, m) return containerRead(ctx, d, m)
} }
// NOTE: this function is NOT used in `read`!s
func containerGetExistingNetworkInterface( func containerGetExistingNetworkInterface(
ctx context.Context, ctx context.Context,
containerAPI *containers.Client, containerAPI *containers.Client,
@ -1943,13 +1944,13 @@ func containerGetExistingNetworkInterface(
return []interface{}{}, fmt.Errorf("error getting container information: %w", err) return []interface{}{}, fmt.Errorf("error getting container information: %w", err)
} }
networkInterfaces := make([]interface{}, 0, len(containerInfo.NetworkInterfaces)) networkInterfacesMap := make(map[string]interface{}, len(containerInfo.NetworkInterfaces))
for _, nv := range containerInfo.NetworkInterfaces { for key, nv := range containerInfo.NetworkInterfaces {
networkInterface := map[string]interface{}{} networkInterface := map[string]interface{}{}
networkInterface[mkNetworkInterfaceEnabled] = true networkInterface[mkNetworkInterfaceEnabled] = true
networkInterface[mkNetworkInterfaceName] = nv.Name networkInterface[mkNetworkInterfaceName] = nv.Name // "eth0", "eth1", etc, same as the `key`
if nv.Bridge != nil { if nv.Bridge != nil {
networkInterface[mkNetworkInterfaceBridge] = *nv.Bridge networkInterface[mkNetworkInterfaceBridge] = *nv.Bridge
@ -1987,10 +1988,10 @@ func containerGetExistingNetworkInterface(
networkInterface[mkNetworkInterfaceMTU] = 0 networkInterface[mkNetworkInterfaceMTU] = 0
} }
networkInterfaces = append(networkInterfaces, networkInterface) networkInterfacesMap[key] = networkInterface
} }
return networkInterfaces, nil return utils.OrderedListFromMap(networkInterfacesMap), nil
} }
func containerGetTagsString(d *schema.ResourceData) string { func containerGetTagsString(d *schema.ResourceData) string {
@ -2449,8 +2450,7 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
diags = append(diags, diag.FromErr(err)...) diags = append(diags, diag.FromErr(err)...)
} }
var ipConfigList []interface{} ipConfigMap := make(map[string]interface{}, len(containerConfig.NetworkInterfaces))
networkInterfacesMap := make(map[string]interface{}, len(containerConfig.NetworkInterfaces)) networkInterfacesMap := make(map[string]interface{}, len(containerConfig.NetworkInterfaces))
for key, nv := range containerConfig.NetworkInterfaces { for key, nv := range containerConfig.NetworkInterfaces {
@ -2473,9 +2473,7 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
ip[mkInitializationIPConfigIPv4Gateway] = "" ip[mkInitializationIPConfigIPv4Gateway] = ""
} }
ipConfig[mkInitializationIPConfigIPv4] = []interface{}{ ipConfig[mkInitializationIPConfigIPv4] = []interface{}{ip}
ip,
}
} else { } else {
ipConfig[mkInitializationIPConfigIPv4] = []interface{}{} ipConfig[mkInitializationIPConfigIPv4] = []interface{}{}
} }
@ -2495,14 +2493,13 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
ip[mkInitializationIPConfigIPv6Gateway] = "" ip[mkInitializationIPConfigIPv6Gateway] = ""
} }
ipConfig[mkInitializationIPConfigIPv6] = []interface{}{ ipConfig[mkInitializationIPConfigIPv6] = []interface{}{ip}
ip,
}
} else { } else {
ipConfig[mkInitializationIPConfigIPv6] = []interface{}{} ipConfig[mkInitializationIPConfigIPv6] = []interface{}{}
} }
ipConfigList = append(ipConfigList, ipConfig) // there is only one set of IP addresses (IPv4 + IPv6) per network interface
ipConfigMap[key] = ipConfig
} }
networkInterface := map[string]interface{}{} networkInterface := map[string]interface{}{}
@ -2550,7 +2547,7 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
} }
networkInterfaces := utils.OrderedListFromMap(networkInterfacesMap) networkInterfaces := utils.OrderedListFromMap(networkInterfacesMap)
initialization[mkInitializationIPConfig] = ipConfigList initialization[mkInitializationIPConfig] = utils.OrderedListFromMap(ipConfigMap)
currentInitialization := d.Get(mkInitialization).([]interface{}) currentInitialization := d.Get(mkInitialization).([]interface{})
@ -2596,10 +2593,7 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
currentNetworkInterface := d.Get(mkNetworkInterface).([]interface{}) currentNetworkInterface := d.Get(mkNetworkInterface).([]interface{})
if len(currentNetworkInterface) > 0 { if len(currentNetworkInterface) > 0 {
err := d.Set( err := d.Set(mkNetworkInterface, networkInterfaces)
mkNetworkInterface,
networkInterfaces,
)
diags = append(diags, diag.FromErr(err)...) diags = append(diags, diag.FromErr(err)...)
} }
} else { } else {