Skip to content
10 changes: 2 additions & 8 deletions source/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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))
}
14 changes: 10 additions & 4 deletions source/istio_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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.
Expand All @@ -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())
Expand Down Expand Up @@ -117,6 +122,7 @@ func NewIstioGatewaySource(
ignoreHostnameAnnotation: ignoreHostnameAnnotation,
serviceInformer: serviceInformer,
gatewayInformer: gatewayInformer,
ingressInformer: ingressInformer,
}, nil
}

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion source/istio_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
}
Expand All @@ -1505,7 +1509,7 @@ func testGatewayEndpoints(t *testing.T) {
context.TODO(),
fakeKubernetesClient,
fakeIstioClient,
ti.targetNamespace,
targetNamespace,
ti.annotationFilter,
ti.fqdnTemplate,
ti.combineFQDNAndAnnotation,
Expand Down
17 changes: 11 additions & 6 deletions source/istio_virtualservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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.
Expand All @@ -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())
Expand Down Expand Up @@ -124,6 +128,7 @@ func NewIstioVirtualServiceSource(
serviceInformer: serviceInformer,
vServiceInformer: virtualServiceInformer,
gatewayInformer: gatewayInformer,
ingressInformer: ingressInformer,
}, nil
}

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -434,15 +439,15 @@ 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
}

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)
Expand Down
Loading