diff --git a/pkg/bgp/server.go b/pkg/bgp/server.go index 5c64aa50..c3af3804 100644 --- a/pkg/bgp/server.go +++ b/pkg/bgp/server.go @@ -15,6 +15,11 @@ import ( gobgp "github.com/osrg/gobgp/v4/pkg/server" ) +type BGPManager interface { + AddHost(ctx context.Context, addr string, object string) error + DelHost(ctx context.Context, addr string, object string) error +} + // Server manages a server object type Server struct { s *gobgp.BgpServer diff --git a/pkg/cluster/service.go b/pkg/cluster/service.go index 6c26b25d..cfb48d55 100644 --- a/pkg/cluster/service.go +++ b/pkg/cluster/service.go @@ -29,8 +29,7 @@ import ( "k8s.io/client-go/kubernetes" ) -func (cluster *Cluster) StartVipService(ctx context.Context, c *kubevip.Config, em *election.Manager, - bgpServer *bgp.Server, killFunc func()) error { +func (cluster *Cluster) StartVipService(ctx context.Context, c *kubevip.Config, em *election.Manager, bgpServer bgp.BGPManager, killFunc func()) error { var err error @@ -302,7 +301,7 @@ func (cluster *Cluster) bgpHealthCheck(ctx context.Context, c *kubevip.Config) ( return healthy, nil } -func (cluster *Cluster) bgpHealthCheckLoop(ctx context.Context, c *kubevip.Config, bgpServer *bgp.Server, vipCIDR string) { +func (cluster *Cluster) bgpHealthCheckLoop(ctx context.Context, c *kubevip.Config, bgpServer bgp.BGPManager, vipCIDR string) { period := time.Duration(c.ControlPlaneHealthCheck.PeriodSeconds) * time.Second consecutiveFailures := 0 @@ -394,7 +393,7 @@ func getNodeIPs(ctx context.Context, nodename string, client *kubernetes.Clients } // StartLoadBalancerService will start a VIP instance and leave it for kube-proxy to handle -func (cluster *Cluster) StartLoadBalancerService(ctx context.Context, c *kubevip.Config, bgp *bgp.Server, name string, wg *sync.WaitGroup) error { +func (cluster *Cluster) StartLoadBalancerService(ctx context.Context, c *kubevip.Config, bgp bgp.BGPManager, name string, wg *sync.WaitGroup) error { // use a Go context so we can tell the arp loop code when we // want to step down //nolint diff --git a/pkg/cluster/service_test.go b/pkg/cluster/service_test.go index c153b1c1..6789e308 100644 --- a/pkg/cluster/service_test.go +++ b/pkg/cluster/service_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/kube-vip/kube-vip/pkg/bgp" "github.com/kube-vip/kube-vip/pkg/cluster" "github.com/kube-vip/kube-vip/pkg/kubevip" "github.com/kube-vip/kube-vip/pkg/route" @@ -28,7 +29,7 @@ func TestBGPHealthCheckLoop_AnnouncesOnHealthy(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - startVipService(t, newTestConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) + startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) expectEventually(t, func() bool { return bgpManager.isAnnounced() }, "route should be announced") @@ -40,7 +41,7 @@ func TestBGPHealthCheckLoop_NoAnnouncementUntilHealthy(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - startVipService(t, newTestConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) + startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) expectConsistently(t, func() bool { return !bgpManager.isAnnounced() }, 2*time.Second, "route should not be announced while unhealthy") @@ -56,7 +57,7 @@ func TestBGPHealthCheckLoop_WithdrawsAfterThreshold(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - cfg := newTestConfig(healthcheck.server.URL, healthcheck.caPath) + cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath) cfg.ControlPlaneHealthCheck.FailureThreshold = 3 startVipService(t, cfg, bgpManager) @@ -78,7 +79,7 @@ func TestBGPHealthCheckLoop_ReAnnouncesOnRecovery(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - cfg := newTestConfig(healthcheck.server.URL, healthcheck.caPath) + cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath) cfg.ControlPlaneHealthCheck.FailureThreshold = 1 startVipService(t, cfg, bgpManager) @@ -100,7 +101,7 @@ func TestBGPHealthCheckLoop_StopsOnContextCancel(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - cancelContext, vipServiceDone := startVipService(t, newTestConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) + cancelContext, vipServiceDone := startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) expectEventually(t, func() bool { return bgpManager.isAnnounced() }, "route should be announced") @@ -121,7 +122,7 @@ func TestBGPHealthCheckLoop_RetriesAddHostOnFailure(t *testing.T) { bgpManager := newMockBGPRouteManager() bgpManager.setAddErr(errTestAddHost) - startVipService(t, newTestConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager) + startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath)) expectConsistently(t, func() bool { return !bgpManager.isAnnounced() }, 2*time.Second, "route should not be announced while AddHost errors") @@ -137,7 +138,7 @@ func TestBGPHealthCheckLoop_RetriesDelHostOnFailure(t *testing.T) { t.Cleanup(healthcheck.server.Close) bgpManager := newMockBGPRouteManager() - cfg := newTestConfig(healthcheck.server.URL, healthcheck.caPath) + cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath) cfg.ControlPlaneHealthCheck.FailureThreshold = 1 startVipService(t, cfg, bgpManager) @@ -195,9 +196,8 @@ func (e *testError) Error() string { return e.msg } // startVipService launches vipService in a goroutine with a mock network and // registers a cleanup to cancel the context and wait for it to finish. // Uses InitCluster so the real code parses certs for the BGP health check client. -func startVipService(t *testing.T, cfg *kubevip.Config, bgpManager *mockBGPRouteManager) (context.CancelFunc, <-chan struct{}) { +func startVipService(t *testing.T, cfg *kubevip.Config, bgpServer bgp.BGPManager) (context.CancelFunc, <-chan struct{}) { t.Helper() - c, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil) if err != nil { t.Fatalf("InitCluster: %v", err) @@ -208,7 +208,7 @@ func startVipService(t *testing.T, cfg *kubevip.Config, bgpManager *mockBGPRoute done := make(chan struct{}) go func() { - _ = c.StartVipService(ctx, cfg, nil, bgpManager, func() {}) + _ = c.StartVipService(ctx, cfg, nil, bgpServer, func() {}) close(done) }() @@ -226,7 +226,7 @@ func startVipService(t *testing.T, cfg *kubevip.Config, bgpManager *mockBGPRoute func startRoutingTableVipService(t *testing.T, cfg *kubevip.Config, network *mockNetwork) { t.Helper() - c, err := cluster.InitCluster(cfg, true, nil, nil, route.NewManager(), nil) + c, err := cluster.InitCluster(cfg, true, nil, nil, route.NewManager(), nil, nil) if err != nil { t.Fatalf("InitCluster: %v", err) } @@ -236,7 +236,7 @@ func startRoutingTableVipService(t *testing.T, cfg *kubevip.Config, network *moc done := make(chan struct{}) go func() { - _ = c.StartVipService(ctx, cfg, nil, nil, func() {}) + _ = c.StartVipService(ctx, cfg, nil, func() {}) close(done) }() @@ -247,14 +247,14 @@ func startRoutingTableVipService(t *testing.T, cfg *kubevip.Config, network *moc } func newRoutingTableConfig(url, caPath string) *kubevip.Config { - cfg := newTestConfig(url, caPath) + cfg := newBGPConfig(url, caPath) cfg.EnableBGP = false cfg.EnableRoutingTable = true cfg.BackendHealthCheckInterval = 1 return cfg } -func newTestConfig(url, caPath string) *kubevip.Config { +func newBGPConfig(url, caPath string) *kubevip.Config { return &kubevip.Config{ EnableBGP: true, ControlPlaneHealthCheck: kubevip.HealthCheck{