Repository: envoyproxy/gateway
Pull request #4296 (2024-09-20 21:12:04)

fix: handle invalid sectionName in BackendTLSPolicy for Backend
Targeting a `sectionName` for `kind:backend` is invalid in BackendTLSPolicy because there is no notion of sections in Backend

Fixes: https://github.com/envoyproxy/gateway/issues/4291

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/4296?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 65.67%. Comparing base [(`91bea68`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/91bea68d1611cb2b083f98c4dcd62a86d183eb09?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`3881c52`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/3881c52ef5d6f732b5834443e1818ef17610b7ca?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #4296      +/-   ##
==========================================
+ Coverage   65.64%   65.67%   +0.02%     
==========================================
  Files         197      197              
  Lines       23555    23557       +2     
==========================================
+ Hits        15462    15470       +8     
+ Misses       6982     6979       -3     
+ Partials     1111     1108       -3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/4296?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).


Patch:
diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go
index d58f2789c..a04f93c9c 100644
--- a/internal/gatewayapi/backendtlspolicy.go
+++ b/internal/gatewayapi/backendtlspolicy.go
@@ -145,7 +145,10 @@ func backendTLSTargetMatched(policy gwapiv1a3.BackendTLSPolicy, target gwapiv1a2
 			target.Kind == currTarget.Kind &&
 			backendNamespace == policy.Namespace &&
 			target.Name == currTarget.Name {
-			if currTarget.SectionName != nil && *currTarget.SectionName != *target.SectionName {
+			if currTarget.SectionName != nil {
+				if target.SectionName != nil && *currTarget.SectionName == *target.SectionName {
+					return true
+				}
 				return false
 			}
 			return true
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index a07ca6ab1..877723fa6 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -1080,7 +1080,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch Gateway CRUDs and reconcile affected GatewayClass.
 	gPredicates := []predicate.TypedPredicate[*gwapiv1.Gateway]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1.Gateway]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.Gateway]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1.Gateway]{}),
 		predicate.NewTypedPredicateFuncs(func(gtw *gwapiv1.Gateway) bool {
 			return r.validateGatewayForReconcile(gtw)
 		}),
@@ -1104,7 +1105,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch HTTPRoute CRUDs and process affected Gateways.
 	httprPredicates := []predicate.TypedPredicate[*gwapiv1.HTTPRoute]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1.HTTPRoute]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.HTTPRoute]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1.HTTPRoute]{}),
 	}
 	if r.namespaceLabel != nil {
 		httprPredicates = append(httprPredicates, predicate.NewTypedPredicateFuncs(func(hr *gwapiv1.HTTPRoute) bool {
@@ -1113,8 +1115,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 	}
 	if err := c.Watch(
 		source.Kind(mgr.GetCache(), &gwapiv1.HTTPRoute{},
-			handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *gwapiv1.HTTPRoute) []reconcile.Request {
-				return r.enqueueClass(ctx, t)
+			handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, route *gwapiv1.HTTPRoute) []reconcile.Request {
+				return r.enqueueClass(ctx, route)
 			}),
 			httprPredicates...)); err != nil {
 		return err
@@ -1125,7 +1127,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch GRPCRoute CRUDs and process affected Gateways.
 	grpcrPredicates := []predicate.TypedPredicate[*gwapiv1.GRPCRoute]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1.GRPCRoute]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.GRPCRoute]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1.GRPCRoute]{}),
 	}
 	if r.namespaceLabel != nil {
 		grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1.GRPCRoute](func(grpc *gwapiv1.GRPCRoute) bool {
@@ -1146,7 +1149,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch TLSRoute CRUDs and process affected Gateways.
 	tlsrPredicates := []predicate.TypedPredicate[*gwapiv1a2.TLSRoute]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TLSRoute]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TLSRoute]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1a2.TLSRoute]{}),
 	}
 	if r.namespaceLabel != nil {
 		tlsrPredicates = append(tlsrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TLSRoute](func(route *gwapiv1a2.TLSRoute) bool {
@@ -1167,7 +1171,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch UDPRoute CRUDs and process affected Gateways.
 	udprPredicates := []predicate.TypedPredicate[*gwapiv1a2.UDPRoute]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1a2.UDPRoute]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.UDPRoute]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1a2.UDPRoute]{}),
 	}
 	if r.namespaceLabel != nil {
 		udprPredicates = append(udprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.UDPRoute](func(route *gwapiv1a2.UDPRoute) bool {
@@ -1188,7 +1193,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
 
 	// Watch TCPRoute CRUDs and process affected Gateways.
 	tcprPredicates := []predicate.TypedPredicate[*gwapiv1a2.TCPRoute]{
-		predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TCPRoute]{},
+		predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TCPRoute]{},
+			predicate.TypedLabelChangedPredicate[*gwapiv1a2.TCPRoute]{}),
 	}
 	if r.namespaceLabel != nil {
 		tcprPredicates = append(tcprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TCPRoute](func(route *gwapiv1a2.TCPRoute) bool {


Test patch:
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
index a92a6be60..5a13fba2f 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
@@ -33,7 +33,11 @@ httpRoutes:
             - name: http-backend
               namespace: default
               port: 8080
-            - name: backend-ip-tls
+            - name: backend-ip-tls-1
+              namespace: default
+              kind: Backend
+              group: gateway.envoyproxy.io
+            - name: backend-ip-tls-2
               namespace: default
               kind: Backend
               group: gateway.envoyproxy.io
@@ -140,13 +144,30 @@ backendTLSPolicies:
   - apiVersion: gateway.networking.k8s.io/v1alpha2
     kind: BackendTLSPolicy
     metadata:
-      name: policy-btls-backend-ip
+      name: policy-btls-backend-ip-1
       namespace: default
     spec:
       targetRefs:
         - group: gateway.envoyproxy.io
           kind: Backend
-          name: backend-ip-tls
+          name: backend-ip-tls-1
+      validation:
+        caCertificateRefs:
+          - name: ca-cmap
+            group: ''
+            kind: ConfigMap
+        hostname: ip-backend
+  - apiVersion: gateway.networking.k8s.io/v1alpha2
+    kind: BackendTLSPolicy
+    metadata:
+      name: policy-btls-backend-ip-2
+      namespace: default
+    spec:
+      targetRefs:
+        - group: gateway.envoyproxy.io
+          kind: Backend
+          name: backend-ip-tls-2
+          sectionName: 3443
       validation:
         caCertificateRefs:
           - name: ca-cmap
@@ -157,10 +178,20 @@ backends:
   - apiVersion: gateway.envoyproxy.io/v1alpha1
     kind: Backend
     metadata:
-      name: backend-ip-tls
+      name: backend-ip-tls-1
       namespace: default
     spec:
       endpoints:
         - ip:
             address: 2.2.2.2
             port: 3443
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: Backend
+    metadata:
+      name: backend-ip-tls-2
+      namespace: default
+    spec:
+      endpoints:
+        - ip:
+            address: 3.3.3.3
+            port: 3443
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
index 66dfad1a1..d07083f26 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
@@ -34,13 +34,13 @@ backendTLSPolicies:
   kind: BackendTLSPolicy
   metadata:
     creationTimestamp: null
-    name: policy-btls-backend-ip
+    name: policy-btls-backend-ip-1
     namespace: default
   spec:
     targetRefs:
     - group: gateway.envoyproxy.io
       kind: Backend
-      name: backend-ip-tls
+      name: backend-ip-tls-1
     validation:
       caCertificateRefs:
       - group: ""
@@ -60,12 +60,32 @@ backendTLSPolicies:
         status: "True"
         type: Accepted
       controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: BackendTLSPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-btls-backend-ip-2
+    namespace: default
+  spec:
+    targetRefs:
+    - group: gateway.envoyproxy.io
+      kind: Backend
+      name: backend-ip-tls-2
+      sectionName: "3443"
+    validation:
+      caCertificateRefs:
+      - group: ""
+        kind: ConfigMap
+        name: ca-cmap
+      hostname: ip-backend
+  status:
+    ancestors: null
 backends:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: Backend
   metadata:
     creationTimestamp: null
-    name: backend-ip-tls
+    name: backend-ip-tls-1
     namespace: default
   spec:
     endpoints:
@@ -79,6 +99,24 @@ backends:
       reason: Accepted
       status: "True"
       type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    creationTimestamp: null
+    name: backend-ip-tls-2
+    namespace: default
+  spec:
+    endpoints:
+    - ip:
+        address: 3.3.3.3
+        port: 3443
+  status:
+    conditions:
+    - lastTransitionTime: null
+      message: The Backend was accepted
+      reason: Accepted
+      status: "True"
+      type: Accepted
 gateways:
 - apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
@@ -139,7 +177,11 @@ httpRoutes:
         port: 8080
       - group: gateway.envoyproxy.io
         kind: Backend
-        name: backend-ip-tls
+        name: backend-ip-tls-1
+        namespace: default
+      - group: gateway.envoyproxy.io
+        kind: Backend
+        name: backend-ip-tls-2
         namespace: default
       matches:
       - path:
@@ -221,9 +263,14 @@ xdsIR:
             tls:
               caCertificate:
                 certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
-                name: policy-btls-backend-ip/default-ca
+                name: policy-btls-backend-ip-1/default-ca
               sni: ip-backend
             weight: 1
+          - addressType: IP
+            endpoints:
+            - host: 3.3.3.3
+              port: 3443
+            weight: 1
         hostname: '*'
         isHTTP2: false
         metadata: