package resolver import ( "context" "fmt" "net/url" "git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox" ) // InterfaceNameStrategy finds the first IP assigned to a named interface (e.g. "mgmt0", "eth0"). type InterfaceNameStrategy struct { name string } func (s *InterfaceNameStrategy) Name() string { return "interface_name" } func (s *InterfaceNameStrategy) Resolve(ctx context.Context, entry *netbox.HostEntry, client *netbox.Client) (string, error) { // NetBox filters IP addresses by interface name with interface= (devices) // and vminterface= (VMs); unknown parameters would be ignored silently and // return every address of the host. A missing interface is an HTTP 400, // which lets the chain try the next strategy. var filterParam string switch entry.Kind { case "device": filterParam = fmt.Sprintf("device_id=%d&interface=%s", entry.ID, url.QueryEscape(s.name)) case "vm": filterParam = fmt.Sprintf("virtual_machine_id=%d&vminterface=%s", entry.ID, url.QueryEscape(s.name)) default: return "", fmt.Errorf("unknown kind %q", entry.Kind) } ips, err := client.GetIPsWithFilterForHost(ctx, *entry, filterParam) if err != nil { return "", fmt.Errorf("fetching IPs for interface %q: %w", s.name, err) } if len(ips) == 0 { return "", ErrNoIP } return ips[0], nil }