package resolver import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" "git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox" ) // newIPServer returns a test server that always responds with the given IP list. func newIPServer(t *testing.T, ips []string) *httptest.Server { t.Helper() type result struct { Address string `json:"address"` } type response struct { Count int `json:"count"` Results []result `json:"results"` } resp := response{Count: len(ips)} for _, ip := range ips { resp.Results = append(resp.Results, result{Address: ip}) } body, _ := json.Marshal(resp) return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Write(body) })) } func TestManagementSubnetStrategy_MatchesSubnet(t *testing.T) { srv := newIPServer(t, []string{"10.0.1.5/24", "192.168.0.1/24"}) defer srv.Close() s, _ := NewManagementSubnetStrategy([]string{"10.0.0.0/8"}) client := netbox.NewClient(srv.URL, "token") ip, err := s.Resolve(context.Background(), &netbox.HostEntry{ID: 1, Kind: "device"}, client) if err != nil { t.Fatalf("unexpected error: %v", err) } if ip != "10.0.1.5" { t.Errorf("got %q, want %q", ip, "10.0.1.5") } } func TestManagementSubnetStrategy_NoMatch(t *testing.T) { srv := newIPServer(t, []string{"192.168.0.1/24"}) defer srv.Close() s, _ := NewManagementSubnetStrategy([]string{"10.0.0.0/8"}) client := netbox.NewClient(srv.URL, "token") _, err := s.Resolve(context.Background(), &netbox.HostEntry{ID: 1, Kind: "device"}, client) if err != ErrNoIP { t.Errorf("no matching subnet should return ErrNoIP, got %v", err) } } func TestManagementSubnetStrategy_FirstMatchWins(t *testing.T) { srv := newIPServer(t, []string{"10.0.1.1/24", "10.0.1.2/24"}) defer srv.Close() s, _ := NewManagementSubnetStrategy([]string{"10.0.0.0/8"}) client := netbox.NewClient(srv.URL, "token") ip, err := s.Resolve(context.Background(), &netbox.HostEntry{ID: 1, Kind: "device"}, client) if err != nil { t.Fatalf("unexpected error: %v", err) } if ip != "10.0.1.1" { t.Errorf("got %q, want first matching IP %q", ip, "10.0.1.1") } } func TestManagementSubnetStrategy_VMKind(t *testing.T) { srv := newIPServer(t, []string{"172.16.5.10/16"}) defer srv.Close() s, _ := NewManagementSubnetStrategy([]string{"172.16.0.0/12"}) client := netbox.NewClient(srv.URL, "token") ip, err := s.Resolve(context.Background(), &netbox.HostEntry{ID: 2, Kind: "vm"}, client) if err != nil { t.Fatalf("unexpected error: %v", err) } if ip != "172.16.5.10" { t.Errorf("got %q, want %q", ip, "172.16.5.10") } } func TestManagementSubnetStrategy_IPv6Subnet(t *testing.T) { srv := newIPServer(t, []string{"fd00::1/64"}) defer srv.Close() s, _ := NewManagementSubnetStrategy([]string{"fd00::/8"}) client := netbox.NewClient(srv.URL, "token") ip, err := s.Resolve(context.Background(), &netbox.HostEntry{ID: 1, Kind: "device"}, client) if err != nil { t.Fatalf("unexpected error: %v", err) } if ip != "fd00::1" { t.Errorf("got %q, want %q", ip, "fd00::1") } }