54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
package resolver
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
|
|
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox"
|
|
)
|
|
|
|
// ManagementSubnetStrategy finds the first IP of a host that falls within
|
|
// one of the configured management subnets.
|
|
type ManagementSubnetStrategy struct {
|
|
subnets []*net.IPNet
|
|
}
|
|
|
|
func NewManagementSubnetStrategy(cidrs []string) (*ManagementSubnetStrategy, error) {
|
|
nets := make([]*net.IPNet, 0, len(cidrs))
|
|
for _, cidr := range cidrs {
|
|
_, ipNet, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid CIDR %q: %w", cidr, err)
|
|
}
|
|
nets = append(nets, ipNet)
|
|
}
|
|
return &ManagementSubnetStrategy{subnets: nets}, nil
|
|
}
|
|
|
|
func (s *ManagementSubnetStrategy) Name() string { return "management_subnet" }
|
|
|
|
func (s *ManagementSubnetStrategy) Resolve(ctx context.Context, entry *netbox.HostEntry, client *netbox.Client) (string, error) {
|
|
if len(s.subnets) == 0 {
|
|
return "", ErrNoIP
|
|
}
|
|
|
|
ips, err := client.GetIPs(ctx, *entry)
|
|
if err != nil {
|
|
return "", fmt.Errorf("fetching IPs: %w", err)
|
|
}
|
|
|
|
for _, rawIP := range ips {
|
|
ip := net.ParseIP(rawIP)
|
|
if ip == nil {
|
|
continue
|
|
}
|
|
for _, subnet := range s.subnets {
|
|
if subnet.Contains(ip) {
|
|
return rawIP, nil
|
|
}
|
|
}
|
|
}
|
|
return "", ErrNoIP
|
|
}
|