0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-29 18:21:10 +00:00

feat(provider): add DNS lookup fallback for node IP resolution (#848)

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2023-12-29 12:24:36 -05:00 committed by GitHub
parent 91e4780af5
commit d398c9c102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 2 deletions

1
.markdownlintignore Normal file
View File

@ -0,0 +1 @@
CHANGELOG.md

View File

@ -7,6 +7,7 @@
"proxmoxtf", "proxmoxtf",
"qcow", "qcow",
"rootfs", "rootfs",
"tflog",
"unmanaged", "unmanaged",
"virtio", "virtio",
"VLANID", "VLANID",

View File

@ -9,6 +9,7 @@ package fwprovider
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"regexp" "regexp"
"strings" "strings"
@ -402,12 +403,14 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
networkDevices, err := nc.ListNetworkInterfaces(ctx) networkDevices, err := nc.ListNetworkInterfaces(ctx)
if err != nil { if err != nil {
return ssh.ProxmoxNode{}, fmt.Errorf("failed to list network devices of node \"%s\": %w", nc.NodeName, err) return ssh.ProxmoxNode{}, fmt.Errorf("failed to list network devices of node %q: %w", nc.NodeName, err)
} }
nodeAddress := "" nodeAddress := ""
// try IPv4 address on the interface with IPv4 gateway // try IPv4 address on the interface with IPv4 gateway
tflog.Debug(ctx, "Attempting to find interfaces with both a static IPV4 address and gateway.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Gateway != nil && d.Address != nil { if d.Gateway != nil && d.Address != nil {
nodeAddress = *d.Address nodeAddress = *d.Address
@ -417,6 +420,8 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
if nodeAddress == "" { if nodeAddress == "" {
// fallback 1: try IPv6 address on the interface with IPv6 gateway // fallback 1: try IPv6 address on the interface with IPv6 gateway
tflog.Debug(ctx, "Attempting to find interfaces with both a static IPV6 address and gateway.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Gateway6 != nil && d.Address6 != nil { if d.Gateway6 != nil && d.Address6 != nil {
nodeAddress = *d.Address6 nodeAddress = *d.Address6
@ -427,6 +432,8 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
if nodeAddress == "" { if nodeAddress == "" {
// fallback 2: use first interface with any IPv4 address // fallback 2: use first interface with any IPv4 address
tflog.Debug(ctx, "Attempting to find interfaces with at least a static IPV4 address.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Address != nil { if d.Address != nil {
nodeAddress = *d.Address nodeAddress = *d.Address
@ -435,6 +442,23 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
} }
} }
if nodeAddress == "" {
// fallback 3: do a good old DNS lookup
tflog.Debug(ctx, fmt.Sprintf("Attempting a DNS lookup of node %q.", nc.NodeName))
ips, err := net.LookupIP(nodeName)
if err != nil {
for _, ip := range ips {
if ipv4 := ip.To4(); ipv4 != nil {
nodeAddress = ipv4.String()
break
}
}
} else {
tflog.Debug(ctx, fmt.Sprintf("Failed to do a DNS lookup of the node: %s", err.Error()))
}
}
if nodeAddress == "" { if nodeAddress == "" {
return ssh.ProxmoxNode{}, fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName) return ssh.ProxmoxNode{}, fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName)
} }

View File

@ -9,8 +9,10 @@ package provider
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"strings" "strings"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@ -176,12 +178,14 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
networkDevices, err := nc.ListNetworkInterfaces(ctx) networkDevices, err := nc.ListNetworkInterfaces(ctx)
if err != nil { if err != nil {
return ssh.ProxmoxNode{}, fmt.Errorf("failed to list network devices of node \"%s\": %w", nc.NodeName, err) return ssh.ProxmoxNode{}, fmt.Errorf("failed to list network devices of node %q: %w", nc.NodeName, err)
} }
nodeAddress := "" nodeAddress := ""
// try IPv4 address on the interface with IPv4 gateway // try IPv4 address on the interface with IPv4 gateway
tflog.Debug(ctx, "Attempting to find interfaces with both a static IPV4 address and gateway.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Gateway != nil && d.Address != nil { if d.Gateway != nil && d.Address != nil {
nodeAddress = *d.Address nodeAddress = *d.Address
@ -191,6 +195,8 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
if nodeAddress == "" { if nodeAddress == "" {
// fallback 1: try IPv6 address on the interface with IPv6 gateway // fallback 1: try IPv6 address on the interface with IPv6 gateway
tflog.Debug(ctx, "Attempting to find interfaces with both a static IPV6 address and gateway.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Gateway6 != nil && d.Address6 != nil { if d.Gateway6 != nil && d.Address6 != nil {
nodeAddress = *d.Address6 nodeAddress = *d.Address6
@ -201,6 +207,8 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
if nodeAddress == "" { if nodeAddress == "" {
// fallback 2: use first interface with any IPv4 address // fallback 2: use first interface with any IPv4 address
tflog.Debug(ctx, "Attempting to find interfaces with at least a static IPV4 address.")
for _, d := range networkDevices { for _, d := range networkDevices {
if d.Address != nil { if d.Address != nil {
nodeAddress = *d.Address nodeAddress = *d.Address
@ -209,6 +217,23 @@ func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (ssh.Proxmox
} }
} }
if nodeAddress == "" {
// fallback 3: do a good old DNS lookup
tflog.Debug(ctx, fmt.Sprintf("Attempting a DNS lookup of node %q.", nc.NodeName))
ips, err := net.LookupIP(nodeName)
if err != nil {
for _, ip := range ips {
if ipv4 := ip.To4(); ipv4 != nil {
nodeAddress = ipv4.String()
break
}
}
} else {
tflog.Debug(ctx, fmt.Sprintf("Failed to do a DNS lookup of the node: %s", err.Error()))
}
}
if nodeAddress == "" { if nodeAddress == "" {
return ssh.ProxmoxNode{}, fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName) return ssh.ProxmoxNode{}, fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName)
} }