diff --git a/source/ingress.go b/source/ingress.go index e0735eba0e..e79d50f161 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -31,7 +31,6 @@ import ( kubeinformers "k8s.io/client-go/informers" netinformers "k8s.io/client-go/informers/networking/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" "sigs.k8s.io/external-dns/source/informers" @@ -100,12 +99,7 @@ func NewIngressSource( ingressInformer := informerFactory.Networking().V1().Ingresses() // Add default resource event handlers to properly initialize informer. - ingressInformer.Informer().AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - }, - }, - ) + _, _ = ingressInformer.Informer().AddEventHandler(informers.DefaultEventHandler()) informerFactory.Start(ctx.Done()) @@ -360,5 +354,5 @@ func (sc *ingressSource) AddEventHandler(ctx context.Context, handler func()) { // Right now there is no way to remove event handler from informer, see: // https://github.com/kubernetes/kubernetes/issues/79610 - sc.ingressInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + _, _ = sc.ingressInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) } diff --git a/source/istio_gateway.go b/source/istio_gateway.go index ce3f177565..e98e3d2d15 100644 --- a/source/istio_gateway.go +++ b/source/istio_gateway.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/labels" kubeinformers "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" + netinformers "k8s.io/client-go/informers/networking/v1" "k8s.io/client-go/kubernetes" "sigs.k8s.io/external-dns/endpoint" @@ -58,6 +59,7 @@ type gatewaySource struct { ignoreHostnameAnnotation bool serviceInformer coreinformers.ServiceInformer gatewayInformer networkingv1beta1informer.GatewayInformer + ingressInformer netinformers.IngressInformer } // NewIstioGatewaySource creates a new gatewaySource with the given config. @@ -82,6 +84,9 @@ func NewIstioGatewaySource( serviceInformer := informerFactory.Core().V1().Services() istioInformerFactory := istioinformers.NewSharedInformerFactory(istioClient, 0) gatewayInformer := istioInformerFactory.Networking().V1beta1().Gateways() + ingressInformer := informerFactory.Networking().V1().Ingresses() + + _, _ = ingressInformer.Informer().AddEventHandler(informers.DefaultEventHandler()) // Add default resource event handlers to properly initialize informer. _, _ = serviceInformer.Informer().AddEventHandler(informers.DefaultEventHandler()) @@ -117,6 +122,7 @@ func NewIstioGatewaySource( ignoreHostnameAnnotation: ignoreHostnameAnnotation, serviceInformer: serviceInformer, gatewayInformer: gatewayInformer, + ingressInformer: ingressInformer, }, nil } @@ -196,7 +202,7 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e } // AddEventHandler adds an event handler that should be triggered if the watched Istio Gateway changes. -func (sc *gatewaySource) AddEventHandler(ctx context.Context, handler func()) { +func (sc *gatewaySource) AddEventHandler(_ context.Context, handler func()) { log.Debug("Adding event handler for Istio Gateway") _, _ = sc.gatewayInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) @@ -226,7 +232,7 @@ func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1beta1.Gatew return filteredList, nil } -func (sc *gatewaySource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *networkingv1beta1.Gateway) (endpoint.Targets, error) { +func (sc *gatewaySource) targetsFromIngress(ingressStr string, gateway *networkingv1beta1.Gateway) (endpoint.Targets, error) { namespace, name, err := ParseIngress(ingressStr) if err != nil { return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err) @@ -237,7 +243,7 @@ func (sc *gatewaySource) targetsFromIngress(ctx context.Context, ingressStr stri targets := make(endpoint.Targets, 0) - ingress, err := sc.kubeClient.NetworkingV1().Ingresses(namespace).Get(ctx, name, metav1.GetOptions{}) + ingress, err := sc.ingressInformer.Lister().Ingresses(namespace).Get(name) if err != nil { log.Error(err) return nil, err @@ -260,7 +266,7 @@ func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networ ingressStr, ok := gateway.Annotations[IstioGatewayIngressSource] if ok && ingressStr != "" { - return sc.targetsFromIngress(ctx, ingressStr, gateway) + return sc.targetsFromIngress(ingressStr, gateway) } return EndpointTargetsFromServices(sc.serviceInformer, sc.namespace, gateway.Spec.Selector) diff --git a/source/istio_gateway_test.go b/source/istio_gateway_test.go index 79a151d2c5..50c02e1851 100644 --- a/source/istio_gateway_test.go +++ b/source/istio_gateway_test.go @@ -1481,6 +1481,7 @@ func testGatewayEndpoints(t *testing.T) { t.Parallel() fakeKubernetesClient := fake.NewClientset() + targetNamespace := ti.targetNamespace for _, lb := range ti.lbServices { service := lb.Service() @@ -1490,6 +1491,9 @@ func testGatewayEndpoints(t *testing.T) { for _, ing := range ti.ingresses { ingress := ing.Ingress() + if ingress.Namespace != targetNamespace { + targetNamespace = v1.NamespaceAll + } _, err := fakeKubernetesClient.NetworkingV1().Ingresses(ingress.Namespace).Create(context.Background(), ingress, metav1.CreateOptions{}) require.NoError(t, err) } @@ -1505,7 +1509,7 @@ func testGatewayEndpoints(t *testing.T) { context.TODO(), fakeKubernetesClient, fakeIstioClient, - ti.targetNamespace, + targetNamespace, ti.annotationFilter, ti.fqdnTemplate, ti.combineFQDNAndAnnotation, diff --git a/source/istio_virtualservice.go b/source/istio_virtualservice.go index 08b0ec4266..f93116903f 100644 --- a/source/istio_virtualservice.go +++ b/source/istio_virtualservice.go @@ -32,10 +32,10 @@ import ( networkingv1beta1informer "istio.io/client-go/pkg/informers/externalversions/networking/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" kubeinformers "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" + netinformers "k8s.io/client-go/informers/networking/v1" "k8s.io/client-go/kubernetes" "sigs.k8s.io/external-dns/endpoint" @@ -61,6 +61,7 @@ type virtualServiceSource struct { serviceInformer coreinformers.ServiceInformer vServiceInformer networkingv1beta1informer.VirtualServiceInformer gatewayInformer networkingv1beta1informer.GatewayInformer + ingressInformer netinformers.IngressInformer } // NewIstioVirtualServiceSource creates a new virtualServiceSource with the given config. @@ -86,6 +87,9 @@ func NewIstioVirtualServiceSource( istioInformerFactory := istioinformers.NewSharedInformerFactoryWithOptions(istioClient, 0, istioinformers.WithNamespace(namespace)) virtualServiceInformer := istioInformerFactory.Networking().V1beta1().VirtualServices() gatewayInformer := istioInformerFactory.Networking().V1beta1().Gateways() + ingressInformer := informerFactory.Networking().V1().Ingresses() + + _, _ = ingressInformer.Informer().AddEventHandler(informers.DefaultEventHandler()) // Add default resource event handlers to properly initialize informer. _, _ = serviceInformer.Informer().AddEventHandler(informers.DefaultEventHandler()) @@ -124,6 +128,7 @@ func NewIstioVirtualServiceSource( serviceInformer: serviceInformer, vServiceInformer: virtualServiceInformer, gatewayInformer: gatewayInformer, + ingressInformer: ingressInformer, }, nil } @@ -292,7 +297,7 @@ func (sc *virtualServiceSource) targetsFromVirtualService(ctx context.Context, v if !virtualServiceBindsToGateway(vService, gw, vsHost) { continue } - tgs, err := sc.targetsFromGateway(ctx, gw) + tgs, err := sc.targetsFromGateway(gw) if err != nil { return targets, err } @@ -407,7 +412,7 @@ func virtualServiceBindsToGateway(vService *v1beta1.VirtualService, gateway *v1b return false } -func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *v1beta1.Gateway) (endpoint.Targets, error) { +func (sc *virtualServiceSource) targetsFromIngress(ingressStr string, gateway *v1beta1.Gateway) (endpoint.Targets, error) { namespace, name, err := ParseIngress(ingressStr) if err != nil { return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err) @@ -416,7 +421,7 @@ func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressS namespace = gateway.Namespace } - ingress, err := sc.kubeClient.NetworkingV1().Ingresses(namespace).Get(ctx, name, metav1.GetOptions{}) + ingress, err := sc.ingressInformer.Lister().Ingresses(namespace).Get(name) if err != nil { log.Error(err) return nil, err @@ -434,7 +439,7 @@ func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressS return targets, nil } -func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway *v1beta1.Gateway) (endpoint.Targets, error) { +func (sc *virtualServiceSource) targetsFromGateway(gateway *v1beta1.Gateway) (endpoint.Targets, error) { targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations) if len(targets) > 0 { return targets, nil @@ -442,7 +447,7 @@ func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway ingressStr, ok := gateway.Annotations[IstioGatewayIngressSource] if ok && ingressStr != "" { - return sc.targetsFromIngress(ctx, ingressStr, gateway) + return sc.targetsFromIngress(ingressStr, gateway) } return EndpointTargetsFromServices(sc.serviceInformer, sc.namespace, gateway.Spec.Selector)