diff --git a/go-controller/pkg/config/config.go b/go-controller/pkg/config/config.go index 736ca68d1b7..de7edc4a1a3 100644 --- a/go-controller/pkg/config/config.go +++ b/go-controller/pkg/config/config.go @@ -80,6 +80,7 @@ var ( APIServer: DefaultAPIServer, RawServiceCIDRs: "172.16.1.0/24", OVNConfigNamespace: "ovn-kubernetes", + EgressIPEnabled: true, } // OvnNorth holds northbound OVN database client and server authentication and location details @@ -199,6 +200,7 @@ type KubernetesConfig struct { OVNEmptyLbEvents bool `gcfg:"ovn-empty-lb-events"` PodIP string `gcfg:"pod-ip"` // UNUSED RawNoHostSubnetNodes string `gcfg:"no-hostsubnet-nodes"` + EgressIPEnabled bool `gcfg:"egress-ip-enable"` NoHostSubnetNodes *metav1.LabelSelector } @@ -644,6 +646,12 @@ var K8sFlags = []cli.Flag{ Name: "pod-ip", Usage: "UNUSED", }, + &cli.BoolFlag{ + Name: "egress-ip-enable", + Usage: "Configure to use EgressIP CRD feature with ovn-kubernetes.", + Destination: &cliConfig.Kubernetes.EgressIPEnabled, + Value: Kubernetes.EgressIPEnabled, + }, &cli.StringFlag{ Name: "no-hostsubnet-nodes", Usage: "Specify a label for nodes that will manage their own hostsubnets", diff --git a/go-controller/pkg/factory/factory.go b/go-controller/pkg/factory/factory.go index 2e725f00920..1dff89778e6 100644 --- a/go-controller/pkg/factory/factory.go +++ b/go-controller/pkg/factory/factory.go @@ -8,6 +8,7 @@ import ( "sync/atomic" "time" + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/metrics" egressipapi "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/egressip/v1" @@ -486,12 +487,7 @@ func NewWatchFactory(c kubernetes.Interface, eip egressipclientset.Interface) (* if err != nil { return nil, err } - wf.informers[egressIPType], err = newInformer(egressIPType, wf.eipFactory.K8s().V1().EgressIPs().Informer()) - if err != nil { - return nil, err - } - wf.eipFactory.Start(wf.stopChan) wf.iFactory.Start(wf.stopChan) for oType, synced := range wf.iFactory.WaitForCacheSync(wf.stopChan) { @@ -500,9 +496,16 @@ func NewWatchFactory(c kubernetes.Interface, eip egressipclientset.Interface) (* } } - for oType, synced := range wf.eipFactory.WaitForCacheSync(wf.stopChan) { - if !synced { - return nil, fmt.Errorf("error in syncing cache for %v informer", oType) + if config.Kubernetes.EgressIPEnabled { + wf.informers[egressIPType], err = newInformer(egressIPType, wf.eipFactory.K8s().V1().EgressIPs().Informer()) + if err != nil { + return nil, err + } + wf.eipFactory.Start(wf.stopChan) + for oType, synced := range wf.eipFactory.WaitForCacheSync(wf.stopChan) { + if !synced { + return nil, fmt.Errorf("error in syncing cache for %v informer", oType) + } } } diff --git a/go-controller/pkg/factory/factory_test.go b/go-controller/pkg/factory/factory_test.go index e7d354e07ae..aefd613d98d 100644 --- a/go-controller/pkg/factory/factory_test.go +++ b/go-controller/pkg/factory/factory_test.go @@ -17,6 +17,7 @@ import ( core "k8s.io/client-go/testing" "k8s.io/client-go/tools/cache" + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" egressip "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/egressip/v1" egressipfake "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/egressip/v1/apis/clientset/versioned/fake" @@ -164,6 +165,10 @@ var _ = Describe("Watch Factory Operations", func() { ) BeforeEach(func() { + + // Restore global default values before each testcase + config.PrepareTestConfig() + fakeClient = &fake.Clientset{} egressIPFakeClient = &egressipfake.Clientset{} @@ -355,6 +360,33 @@ var _ = Describe("Watch Factory Operations", func() { }) }) + Context("when EgressIP is disabled", func() { + testExisting := func(objType reflect.Type) { + wf, err = NewWatchFactory(fakeClient, egressIPFakeClient) + Expect(err).NotTo(HaveOccurred()) + var addCalls int32 + h, err := wf.addHandler(objType, "", nil, + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + atomic.AddInt32(&addCalls, 1) + }, + UpdateFunc: func(old, new interface{}) {}, + DeleteFunc: func(obj interface{}) {}, + }, func(existing []interface{}) { + atomic.AddInt32(&addCalls, int32(len(existing))) + }) + Expect(err).NotTo(HaveOccurred()) + Expect(int(addCalls)).To(Equal(0)) + wf.removeHandler(objType, h) + } + It("does not call ADD for each existing egressIP", func() { + config.Kubernetes.EgressIPEnabled = false + egressIPs = append(egressIPs, newEgressIP("myEgressIP", "default")) + egressIPs = append(egressIPs, newEgressIP("myEgressIP1", "default")) + testExisting(egressIPType) + }) + }) + addFilteredHandler := func(wf *WatchFactory, objType reflect.Type, namespace string, lsel *metav1.LabelSelector, funcs cache.ResourceEventHandlerFuncs) (*Handler, *handlerCalls) { calls := handlerCalls{} h, err := wf.addHandler(objType, namespace, lsel, cache.ResourceEventHandlerFuncs{ diff --git a/go-controller/pkg/node/gateway_localnet.go b/go-controller/pkg/node/gateway_localnet.go index 85d715bb5ff..cf479e4d79f 100644 --- a/go-controller/pkg/node/gateway_localnet.go +++ b/go-controller/pkg/node/gateway_localnet.go @@ -180,8 +180,10 @@ func (n *OvnNode) initLocalEgressIP(gatewayIfAddrs []*net.IPNet) error { nodeName: n.name, defaultGatewayIntf: n.defaultGatewayIntf, } - if err := n.watchEgressIP(egressIPLocal); err != nil { - return err + if config.Kubernetes.EgressIPEnabled { + if err := n.watchEgressIP(egressIPLocal); err != nil { + return err + } } return nil } diff --git a/go-controller/pkg/ovn/ovn.go b/go-controller/pkg/ovn/ovn.go index d227b865d5f..737f812ea6d 100644 --- a/go-controller/pkg/ovn/ovn.go +++ b/go-controller/pkg/ovn/ovn.go @@ -256,11 +256,21 @@ func (oc *Controller) Run() error { } for _, f := range []func() error{oc.WatchNamespaces, oc.WatchPods, oc.WatchServices, - oc.WatchEndpoints, oc.WatchNetworkPolicy, oc.WatchEgressNodes, oc.WatchEgressIP} { + oc.WatchEndpoints, oc.WatchNetworkPolicy} { if err := f(); err != nil { return err } } + + if config.Kubernetes.EgressIPEnabled { + if err := oc.WatchEgressNodes(); err != nil { + return err + } + if err := oc.WatchEgressIP(); err != nil { + return err + } + } + klog.Infof("Completing all the Watchers took %v", time.Since(start)) if config.Kubernetes.OVNEmptyLbEvents {