a4fa33d224
Release / release (push) Successful in 51s
API client: - NewClient now accepts tokenVersion (0 = auto-detect from token prefix) - tokenVersion stored on Client, used for 403 error hints - All callers pass cfg.NetBox.TokenVersion Tests added: - netbox: TokenVersion, NewClient auto-detect, explicit version, 403 v1 hint, 403 v2 no-hint, Authorization header verification - config: token_version preserved/auto-detected, defaults, missing file, invalid YAML, Path() - setup: save roundtrip, file permissions (0600), empty fields omitted, dir creation, full save→load roundtrip Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
110 lines
3.1 KiB
Go
110 lines
3.1 KiB
Go
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", 0)
|
|
|
|
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", 0)
|
|
|
|
_, 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", 0)
|
|
|
|
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", 0)
|
|
|
|
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", 0)
|
|
|
|
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")
|
|
}
|
|
}
|