@@ -6,8 +6,13 @@ import (
6
6
"github.com/pkg/errors"
7
7
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8
8
"k8s.io/apimachinery/pkg/types"
9
+ "k8s.io/apimachinery/pkg/util/sets"
9
10
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
11
+ "sigs.k8s.io/aws-load-balancer-controller/controllers/gateway/eventhandlers"
12
+ "sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
10
13
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/routeutils"
14
+ "sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
15
+ "sigs.k8s.io/aws-load-balancer-controller/pkg/shared_constants"
11
16
"sigs.k8s.io/controller-runtime/pkg/client"
12
17
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
13
18
"sort"
@@ -180,3 +185,94 @@ func generateRouteList(listenerRoutes map[int32][]routeutils.RouteDescriptor) st
180
185
181
186
return strings .Join (allRoutes , "," )
182
187
}
188
+
189
+ // AddLoadBalancerConfigurationFinalizers add finalizer to load balancer configuration when it is in use by gateway or gatewayClass
190
+ func AddLoadBalancerConfigurationFinalizers (ctx context.Context , gw * gwv1.Gateway , gwClass * gwv1.GatewayClass , k8sClient client.Client , manager k8s.FinalizerManager ) error {
191
+ // add finalizer to lbConfig referred by gatewayClass
192
+ if gwClass .Spec .ParametersRef != nil && string (gwClass .Spec .ParametersRef .Kind ) == constants .LoadBalancerConfiguration {
193
+ lbConfig := & elbv2gw.LoadBalancerConfiguration {}
194
+ if err := k8sClient .Get (ctx , types.NamespacedName {
195
+ Namespace : string (* gwClass .Spec .ParametersRef .Namespace ),
196
+ Name : gwClass .Spec .ParametersRef .Name ,
197
+ }, lbConfig ); err != nil {
198
+ return client .IgnoreNotFound (err )
199
+ }
200
+ if err := manager .AddFinalizers (ctx , lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ); err != nil {
201
+ return err
202
+ }
203
+ }
204
+
205
+ // add finalizer to lbConfig referred by gateway
206
+ if gw .Spec .Infrastructure != nil && gw .Spec .Infrastructure .ParametersRef != nil && string (gw .Spec .Infrastructure .ParametersRef .Kind ) == constants .LoadBalancerConfiguration {
207
+ lbConfig := & elbv2gw.LoadBalancerConfiguration {}
208
+ if err := k8sClient .Get (ctx , types.NamespacedName {
209
+ Namespace : gw .Namespace ,
210
+ Name : gw .Spec .Infrastructure .ParametersRef .Name ,
211
+ }, lbConfig ); err != nil {
212
+ return client .IgnoreNotFound (err )
213
+ }
214
+ if err := manager .AddFinalizers (ctx , lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ); err != nil {
215
+ return err
216
+ }
217
+ }
218
+ return nil
219
+ }
220
+
221
+ func RemoveLoadBalancerConfigurationFinalizers (ctx context.Context , gw * gwv1.Gateway , gwClass * gwv1.GatewayClass , k8sClient client.Client , manager k8s.FinalizerManager , controllerName string ) error {
222
+ // remove finalizer from lbConfig - gatewayClass
223
+ if gwClass .Spec .ParametersRef != nil && string (gwClass .Spec .ParametersRef .Kind ) == constants .LoadBalancerConfiguration {
224
+ lbConfig := & elbv2gw.LoadBalancerConfiguration {}
225
+ if err := k8sClient .Get (ctx , types.NamespacedName {
226
+ Namespace : string (* gwClass .Spec .ParametersRef .Namespace ),
227
+ Name : gwClass .Spec .ParametersRef .Name ,
228
+ }, lbConfig ); err != nil {
229
+ return client .IgnoreNotFound (err )
230
+ }
231
+ // remove finalizer if it exists and it not in use
232
+ if k8s .HasFinalizer (lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ) && ! isLBConfigInUse (ctx , lbConfig , gw , gwClass , k8sClient , controllerName ) {
233
+ if err := manager .RemoveFinalizers (ctx , lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ); err != nil {
234
+ return err
235
+ }
236
+ }
237
+ }
238
+
239
+ // remove finalizer from lbConfig - gateway
240
+ if gw .Spec .Infrastructure != nil && gw .Spec .Infrastructure .ParametersRef != nil && string (gw .Spec .Infrastructure .ParametersRef .Kind ) == constants .LoadBalancerConfiguration {
241
+ lbConfig := & elbv2gw.LoadBalancerConfiguration {}
242
+ if err := k8sClient .Get (ctx , types.NamespacedName {
243
+ Namespace : gw .Namespace ,
244
+ Name : gw .Spec .Infrastructure .ParametersRef .Name ,
245
+ }, lbConfig ); err != nil {
246
+ return client .IgnoreNotFound (err )
247
+ }
248
+ // remove finalizer if it exists and it is not in use
249
+ if k8s .HasFinalizer (lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ) && ! isLBConfigInUse (ctx , lbConfig , gw , gwClass , k8sClient , controllerName ) {
250
+ if err := manager .RemoveFinalizers (ctx , lbConfig , shared_constants .LoadBalancerConfigurationFinalizer ); err != nil {
251
+ //r.eventRecorder.Event(gw, corev1.EventTypeWarning, LoadBalancerConfigurationEventReasonFailedRemoveFinalizer, fmt.Sprintf("Failed to remove load balancer configuration finalizer due to %v", err))
252
+ return err
253
+ }
254
+ }
255
+ }
256
+ return nil
257
+ }
258
+
259
+ func isLBConfigInUse (ctx context.Context , lbConfig * elbv2gw.LoadBalancerConfiguration , gw * gwv1.Gateway , gwClass * gwv1.GatewayClass , k8sClient client.Client , controllerName string ) bool {
260
+ // check if lbConfig is referred by any other gateway
261
+ gwsUsingLBConfig := eventhandlers .GetImpactedGatewaysFromLbConfig (ctx , k8sClient , lbConfig , controllerName )
262
+ for _ , gwUsingLBConfig := range gwsUsingLBConfig {
263
+ if gwUsingLBConfig .Name != gw .Name || gwUsingLBConfig .Namespace != gw .Namespace {
264
+ return true
265
+ }
266
+ }
267
+
268
+ // check if lbConfig is referred by any other gatewayClass
269
+ gwClassesUsingLBConfig := eventhandlers .GetImpactedGatewayClassesFromLbConfig (ctx , k8sClient , lbConfig , sets .New (controllerName ))
270
+ for _ , gwClassUsingLBConfig := range gwClassesUsingLBConfig {
271
+ // at this point, no other gateway and gatewayClass is using LBConfig, only the given GWClass is using it, we remove finalizer here
272
+ // if we do not handle it here, no gateway will trigger reconcile deletion to remove finalizer from this gatewayClass
273
+ if gwClassUsingLBConfig .Name != gwClass .Name || gwClassUsingLBConfig .Namespace != gwClass .Namespace {
274
+ return true
275
+ }
276
+ }
277
+ return false
278
+ }
0 commit comments