Skip to content

Commit 88f7c1c

Browse files
authored
Merge pull request #4430 from zac-nixon/znixon/gw-api-alb-nlb-try2
[gw api] Implement ALB target of NLB
2 parents d37f75c + 5599bda commit 88f7c1c

37 files changed

+2332
-730
lines changed

apis/gateway/v1beta1/targetgroupconfig_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
2020
limitations under the License.
2121
*/
2222

23-
// Reference defines how to look up the Target Group configuration for a service.
23+
// Reference defines how to look up the Target Group configuration for a kubernetes object.
2424
type Reference struct {
2525
// Group is the group of the referent. For example, "gateway.networking.k8s.io".
2626
// When unspecified or empty string, core API group is inferred.
@@ -108,7 +108,7 @@ const (
108108
TargetTypeIP TargetType = "ip"
109109
)
110110

111-
// +kubebuilder:validation:Enum=http;https;tcp
111+
// +kubebuilder:validation:Enum=HTTP;HTTPS;TCP
112112
type TargetGroupHealthCheckProtocol string
113113

114114
const (

config/crd/gateway/gateway-crds.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,9 @@ spec:
821821
with the target. The GENEVE, TLS, UDP, and TCP_UDP protocols
822822
are not supported for health checks.
823823
enum:
824-
- http
825-
- https
826-
- tcp
824+
- HTTP
825+
- HTTPS
826+
- TCP
827827
type: string
828828
healthCheckTimeout:
829829
description: healthCheckTimeout The amount of time, in seconds,
@@ -1014,9 +1014,9 @@ spec:
10141014
and TCP_UDP protocols are not supported for health
10151015
checks.
10161016
enum:
1017-
- http
1018-
- https
1019-
- tcp
1017+
- HTTP
1018+
- HTTPS
1019+
- TCP
10201020
type: string
10211021
healthCheckTimeout:
10221022
description: healthCheckTimeout The amount of time,

config/crd/gateway/gateway.k8s.aws_targetgroupconfigurations.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ spec:
8282
with the target. The GENEVE, TLS, UDP, and TCP_UDP protocols
8383
are not supported for health checks.
8484
enum:
85-
- http
86-
- https
87-
- tcp
85+
- HTTP
86+
- HTTPS
87+
- TCP
8888
type: string
8989
healthCheckTimeout:
9090
description: healthCheckTimeout The amount of time, in seconds,
@@ -275,9 +275,9 @@ spec:
275275
and TCP_UDP protocols are not supported for health
276276
checks.
277277
enum:
278-
- http
279-
- https
280-
- tcp
278+
- HTTP
279+
- HTTPS
280+
- TCP
281281
type: string
282282
healthCheckTimeout:
283283
description: healthCheckTimeout The amount of time,

controllers/gateway/eventhandlers/target_group_configuration_events.go

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/go-logr/logr"
66
corev1 "k8s.io/api/core/v1"
77
"k8s.io/apimachinery/pkg/types"
8+
"k8s.io/apimachinery/pkg/util/sets"
89
"k8s.io/client-go/tools/record"
910
"k8s.io/client-go/util/workqueue"
1011
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
@@ -13,66 +14,122 @@ import (
1314
"sigs.k8s.io/controller-runtime/pkg/event"
1415
"sigs.k8s.io/controller-runtime/pkg/handler"
1516
"sigs.k8s.io/controller-runtime/pkg/reconcile"
17+
gwalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
1618
)
1719

1820
// NewEnqueueRequestsForTargetGroupConfigurationEvent creates handler for TargetGroupConfiguration resources
19-
func NewEnqueueRequestsForTargetGroupConfigurationEvent(svcEventChan chan<- event.TypedGenericEvent[*corev1.Service],
21+
func NewEnqueueRequestsForTargetGroupConfigurationEvent(svcEventChan chan<- event.TypedGenericEvent[*corev1.Service], tcpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TCPRoute],
2022
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*elbv2gw.TargetGroupConfiguration, reconcile.Request] {
2123
return &enqueueRequestsForTargetGroupConfigurationEvent{
22-
svcEventChan: svcEventChan,
23-
k8sClient: k8sClient,
24-
eventRecorder: eventRecorder,
25-
logger: logger,
24+
svcEventChan: svcEventChan,
25+
tcpRouteEventChan: tcpRouteEventChan,
26+
k8sClient: k8sClient,
27+
eventRecorder: eventRecorder,
28+
logger: logger,
2629
}
2730
}
2831

2932
var _ handler.TypedEventHandler[*elbv2gw.TargetGroupConfiguration, reconcile.Request] = (*enqueueRequestsForTargetGroupConfigurationEvent)(nil)
3033

3134
// enqueueRequestsForTargetGroupConfigurationEvent handles TargetGroupConfiguration events
3235
type enqueueRequestsForTargetGroupConfigurationEvent struct {
33-
svcEventChan chan<- event.TypedGenericEvent[*corev1.Service]
34-
k8sClient client.Client
35-
eventRecorder record.EventRecorder
36-
logger logr.Logger
36+
svcEventChan chan<- event.TypedGenericEvent[*corev1.Service]
37+
tcpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TCPRoute]
38+
k8sClient client.Client
39+
eventRecorder record.EventRecorder
40+
logger logr.Logger
3741
}
3842

3943
func (h *enqueueRequestsForTargetGroupConfigurationEvent) Create(ctx context.Context, e event.TypedCreateEvent[*elbv2gw.TargetGroupConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
4044
tgconfigNew := e.Object
4145
h.logger.V(1).Info("enqueue targetgroupconfiguration create event", "targetgroupconfiguration", tgconfigNew.Name)
42-
h.enqueueImpactedService(ctx, tgconfigNew, queue)
46+
h.enqueueImpactedObject(ctx, tgconfigNew, queue)
4347
}
4448

4549
func (h *enqueueRequestsForTargetGroupConfigurationEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*elbv2gw.TargetGroupConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
4650
tgconfigNew := e.ObjectNew
4751
h.logger.V(1).Info("enqueue targetgroupconfiguration update event", "targetgroupconfiguration", tgconfigNew.Name)
48-
h.enqueueImpactedService(ctx, tgconfigNew, queue)
52+
h.enqueueImpactedObject(ctx, tgconfigNew, queue)
4953
}
5054

5155
func (h *enqueueRequestsForTargetGroupConfigurationEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*elbv2gw.TargetGroupConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
5256
tgconfig := e.Object
5357
h.logger.V(1).Info("enqueue targetgroupconfiguration delete event", "targetgroupconfiguration", tgconfig.Name)
54-
h.enqueueImpactedService(ctx, tgconfig, queue)
58+
h.enqueueImpactedObject(ctx, tgconfig, queue)
5559
}
5660

5761
func (h *enqueueRequestsForTargetGroupConfigurationEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*elbv2gw.TargetGroupConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
5862
tgconfig := e.Object
5963
h.logger.V(1).Info("enqueue targetgroupconfiguration generic event", "targetgroupconfiguration", tgconfig.Name)
60-
h.enqueueImpactedService(ctx, tgconfig, queue)
64+
h.enqueueImpactedObject(ctx, tgconfig, queue)
6165
}
6266

63-
func (h *enqueueRequestsForTargetGroupConfigurationEvent) enqueueImpactedService(ctx context.Context, tgconfig *elbv2gw.TargetGroupConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
64-
svcName := types.NamespacedName{Namespace: tgconfig.Namespace, Name: tgconfig.Spec.TargetReference.Name}
65-
svc := &corev1.Service{}
66-
if err := h.k8sClient.Get(ctx, svcName, svc); err != nil {
67-
h.logger.V(1).Info("ignoring targetgroupconfiguration event for unknown service",
67+
func (h *enqueueRequestsForTargetGroupConfigurationEvent) enqueueImpactedObject(ctx context.Context, tgconfig *elbv2gw.TargetGroupConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
68+
objName := types.NamespacedName{Namespace: tgconfig.Namespace, Name: tgconfig.Spec.TargetReference.Name}
69+
70+
if tgconfig.Spec.TargetReference.Kind == nil || *tgconfig.Spec.TargetReference.Kind == "Service" {
71+
svc := &corev1.Service{}
72+
if err := h.k8sClient.Get(ctx, objName, svc); err != nil {
73+
h.logger.V(1).Info("ignoring targetgroupconfiguration event for unknown service",
74+
"targetgroupconfiguration", k8s.NamespacedName(tgconfig),
75+
"service", k8s.NamespacedName(svc))
76+
return
77+
}
78+
h.logger.V(1).Info("enqueue service for targetgroupconfiguration event",
6879
"targetgroupconfiguration", k8s.NamespacedName(tgconfig),
6980
"service", k8s.NamespacedName(svc))
70-
return
81+
h.svcEventChan <- event.TypedGenericEvent[*corev1.Service]{
82+
Object: svc,
83+
}
84+
}
85+
86+
// TODO - We should probably use an indexer here, we have a task to do this.
87+
if tgconfig.Spec.TargetReference.Kind != nil && *tgconfig.Spec.TargetReference.Kind == "Gateway" && h.tcpRouteEventChan != nil {
88+
tcpRouteList := &gwalpha2.TCPRouteList{}
89+
90+
if err := h.k8sClient.List(ctx, tcpRouteList); err != nil {
91+
h.logger.V(1).Info("failed to list tcp routes for target group configuration event", "targetgroupconfiguration", k8s.NamespacedName(tgconfig))
92+
return
93+
}
94+
95+
impactedRoutes := getImpactedTCPRoutes(tcpRouteList, tgconfig)
96+
for i := range impactedRoutes {
97+
h.tcpRouteEventChan <- event.TypedGenericEvent[*gwalpha2.TCPRoute]{
98+
Object: impactedRoutes[i],
99+
}
100+
}
101+
71102
}
72-
h.logger.V(1).Info("enqueue service for targetgroupconfiguration event",
73-
"targetgroupconfiguration", k8s.NamespacedName(tgconfig),
74-
"service", k8s.NamespacedName(svc))
75-
h.svcEventChan <- event.TypedGenericEvent[*corev1.Service]{
76-
Object: svc,
103+
}
104+
105+
func getImpactedTCPRoutes(list *gwalpha2.TCPRouteList, tgconfig *elbv2gw.TargetGroupConfiguration) []*gwalpha2.TCPRoute {
106+
seen := sets.Set[types.NamespacedName]{}
107+
res := make([]*gwalpha2.TCPRoute, 0)
108+
109+
for i, route := range list.Items {
110+
nsn := k8s.NamespacedName(&route)
111+
for _, rule := range route.Spec.Rules {
112+
for _, beRef := range rule.BackendRefs {
113+
if beRef.Kind != nil && *beRef.Kind == "Gateway" {
114+
if string(beRef.Name) == tgconfig.Spec.TargetReference.Name {
115+
116+
// The route backend ns
117+
var routeNs string
118+
if beRef.Namespace == nil {
119+
routeNs = route.Namespace
120+
} else {
121+
routeNs = string(*beRef.Namespace)
122+
}
123+
124+
if routeNs == tgconfig.Namespace && !seen.Has(nsn) {
125+
res = append(res, &list.Items[i])
126+
seen.Insert(nsn)
127+
}
128+
129+
}
130+
}
131+
}
132+
}
77133
}
134+
return res
78135
}

0 commit comments

Comments
 (0)