diff --git a/docs/annotations/annotations.md b/docs/annotations/annotations.md index 79957c1393..a880674f8c 100644 --- a/docs/annotations/annotations.md +++ b/docs/annotations/annotations.md @@ -12,7 +12,7 @@ The following table documents which sources support which annotations: | CloudFoundry | | | | | | | | CRD | | | | | | | | F5 | | | | | Yes | | -| Gateway | Yes | Yes[^1] | | | Yes | Yes | +| Gateway | Yes | Yes[^1] | | Yes[^4] | Yes | Yes | | Gloo | | | | | Yes | Yes | | Ingress | Yes | Yes[^1] | | Yes | Yes | Yes | | Istio | Yes | Yes[^1] | | Yes | Yes | Yes | @@ -27,6 +27,7 @@ The following table documents which sources support which annotations: [^1]: Unless the `--ignore-hostname-annotation` flag is specified. [^2]: Only behaves differently than `hostname` for `Service`s of type `LoadBalancer`. [^3]: Also supported on `Pods` referenced from a headless `Service`'s `Endpoints`. +[^4]: The annotation should be on the `Gateway` ## external-dns.alpha.kubernetes.io/access diff --git a/source/gateway.go b/source/gateway.go index 6ca9b0bfcc..f48834f638 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -352,8 +352,12 @@ func (c *gatewayRouteResolver) resolve(rt gatewayRoute) (map[string]endpoint.Tar if !ok { continue } - for _, addr := range gw.gateway.Status.Addresses { - hostTargets[host] = append(hostTargets[host], addr.Value) + override := getTargetsFromTargetAnnotation(gw.gateway.Annotations) + hostTargets[host] = append(hostTargets[host], override...) + if len(override) == 0 { + for _, addr := range gw.gateway.Status.Addresses { + hostTargets[host] = append(hostTargets[host], addr.Value) + } } match = true } diff --git a/source/gateway_httproute_test.go b/source/gateway_httproute_test.go index 28926705db..f57969ec42 100644 --- a/source/gateway_httproute_test.go +++ b/source/gateway_httproute_test.go @@ -1033,6 +1033,91 @@ func TestGatewayHTTPRouteSourceEndpoints(t *testing.T) { }}, endpoints: nil, }, + { + title: "AnnotationOverride", + config: Config{ + GatewayNamespace: "gateway-namespace", + }, + namespaces: namespaces("gateway-namespace", "route-namespace"), + gateways: []*v1beta1.Gateway{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "overriden-gateway", + Namespace: "gateway-namespace", + Annotations: map[string]string{ + targetAnnotationKey: "4.3.2.1", + }, + }, + Spec: v1beta1.GatewaySpec{ + Listeners: []v1beta1.Listener{{ + Protocol: v1beta1.HTTPProtocolType, + AllowedRoutes: allowAllNamespaces, + }}, + }, + Status: gatewayStatus("1.2.3.4"), + }, + }, + routes: []*v1beta1.HTTPRoute{{ + ObjectMeta: objectMeta("route-namespace", "test"), + Spec: v1beta1.HTTPRouteSpec{ + Hostnames: hostnames("test.example.internal"), + }, + Status: httpRouteStatus( // The route is attached to both gateways. + gatewayParentRef("gateway-namespace", "overriden-gateway"), + ), + }}, + endpoints: []*endpoint.Endpoint{ + newTestEndpoint("test.example.internal", "A", "4.3.2.1"), + }, + }, + { + title: "MutlipleGatewaysOneAnnotationOverride", + config: Config{ + GatewayNamespace: "gateway-namespace", + }, + namespaces: namespaces("gateway-namespace", "route-namespace"), + gateways: []*v1beta1.Gateway{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "overriden-gateway", + Namespace: "gateway-namespace", + Annotations: map[string]string{ + targetAnnotationKey: "4.3.2.1", + }, + }, + Spec: v1beta1.GatewaySpec{ + Listeners: []v1beta1.Listener{{ + Protocol: v1beta1.HTTPProtocolType, + AllowedRoutes: allowAllNamespaces, + }}, + }, + Status: gatewayStatus("1.2.3.4"), + }, + { + ObjectMeta: objectMeta("gateway-namespace", "test"), + Spec: v1beta1.GatewaySpec{ + Listeners: []v1beta1.Listener{{ + Protocol: v1beta1.HTTPProtocolType, + AllowedRoutes: allowAllNamespaces, + }}, + }, + Status: gatewayStatus("2.3.4.5"), + }, + }, + routes: []*v1beta1.HTTPRoute{{ + ObjectMeta: objectMeta("route-namespace", "test"), + Spec: v1beta1.HTTPRouteSpec{ + Hostnames: hostnames("test.example.internal"), + }, + Status: httpRouteStatus( // The route is attached to both gateways. + gatewayParentRef("gateway-namespace", "overriden-gateway"), + gatewayParentRef("gateway-namespace", "test"), + ), + }}, + endpoints: []*endpoint.Endpoint{ + newTestEndpoint("test.example.internal", "A", "4.3.2.1", "2.3.4.5"), + }, + }, } for _, tt := range tests { tt := tt