You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by as...@apache.org on 2025/08/21 09:00:44 UTC

(apisix-ingress-controller) branch master updated: fix: support tlsSecret from http.backends in ApisixRoute (#2518)

This is an automated email from the ASF dual-hosted git repository.

ashishtiwari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new 6bc3731a fix: support tlsSecret from http.backends in ApisixRoute (#2518)
6bc3731a is described below

commit 6bc3731a5c7fee65fe7e1f141484272843ab2bfa
Author: Ashish Tiwari <as...@gmail.com>
AuthorDate: Thu Aug 21 14:30:40 2025 +0530

    fix: support tlsSecret from http.backends in ApisixRoute (#2518)
---
 internal/controller/apisixroute_controller.go | 71 +++++++++++++++++----------
 test/e2e/crds/v2/route.go                     | 57 +++++++++++++++++++++
 2 files changed, 101 insertions(+), 27 deletions(-)

diff --git a/internal/controller/apisixroute_controller.go b/internal/controller/apisixroute_controller.go
index ff43f605..4e9ff5cd 100644
--- a/internal/controller/apisixroute_controller.go
+++ b/internal/controller/apisixroute_controller.go
@@ -288,6 +288,43 @@ func (r *ApisixRouteReconciler) validateSecrets(ctx context.Context, tc *provide
 	return nil
 }
 
+func (r *ApisixRouteReconciler) processExternalNodes(ctx context.Context, tc *provider.TranslateContext, ups apiv2.ApisixUpstream) error {
+	for _, node := range ups.Spec.ExternalNodes {
+		if node.Type == apiv2.ExternalTypeService {
+			var (
+				service   corev1.Service
+				serviceNN = k8stypes.NamespacedName{Namespace: ups.GetNamespace(), Name: node.Name}
+			)
+			if err := r.Get(ctx, serviceNN, &service); err != nil {
+				r.Log.Error(err, "failed to get service in ApisixUpstream", "ApisixUpstream", ups.Name, "Service", serviceNN)
+				if client.IgnoreNotFound(err) == nil {
+					continue
+				}
+				return err
+			}
+			tc.Services[utils.NamespacedName(&service)] = &service
+		}
+	}
+	return nil
+}
+
+func (r *ApisixRouteReconciler) processTLSSecret(ctx context.Context, tc *provider.TranslateContext, ups apiv2.ApisixUpstream, secretNs string) error {
+	if ups.Spec.TLSSecret != nil && ups.Spec.TLSSecret.Name != "" {
+		var (
+			secret   corev1.Secret
+			secretNN = k8stypes.NamespacedName{Namespace: cmp.Or(ups.Spec.TLSSecret.Namespace, secretNs), Name: ups.Spec.TLSSecret.Name}
+		)
+		if err := r.Get(ctx, secretNN, &secret); err != nil {
+			r.Log.Error(err, "failed to get secret in ApisixUpstream", "ApisixUpstream", ups.Name, "Secret", secretNN)
+			if client.IgnoreNotFound(err) != nil {
+				return err
+			}
+		}
+		tc.Secrets[secretNN] = &secret
+	}
+	return nil
+}
+
 func (r *ApisixRouteReconciler) validateBackends(ctx context.Context, tc *provider.TranslateContext, in *apiv2.ApisixRoute, http apiv2.ApisixRouteHTTP) error {
 	var backends = make(map[k8stypes.NamespacedName]struct{})
 	for _, backend := range http.Backends {
@@ -324,6 +361,9 @@ func (r *ApisixRouteReconciler) validateBackends(ctx context.Context, tc *provid
 			}
 		} else {
 			tc.Upstreams[serviceNN] = &au
+			if err := r.processTLSSecret(ctx, tc, au, in.GetNamespace()); err != nil {
+				return err
+			}
 		}
 
 		if service.Spec.Type == corev1.ServiceTypeExternalName {
@@ -387,35 +427,12 @@ func (r *ApisixRouteReconciler) validateUpstreams(ctx context.Context, tc *provi
 		}
 		tc.Upstreams[upsNN] = &ups
 
-		for _, node := range ups.Spec.ExternalNodes {
-			if node.Type == apiv2.ExternalTypeService {
-				var (
-					service   corev1.Service
-					serviceNN = k8stypes.NamespacedName{Namespace: ups.GetNamespace(), Name: node.Name}
-				)
-				if err := r.Get(ctx, serviceNN, &service); err != nil {
-					r.Log.Error(err, "failed to get service in ApisixUpstream", "ApisixUpstream", upsNN, "Service", serviceNN)
-					if client.IgnoreNotFound(err) == nil {
-						continue
-					}
-					return err
-				}
-				tc.Services[utils.NamespacedName(&service)] = &service
-			}
+		if err := r.processExternalNodes(ctx, tc, ups); err != nil {
+			return err
 		}
 
-		if ups.Spec.TLSSecret != nil && ups.Spec.TLSSecret.Name != "" {
-			var (
-				secret   corev1.Secret
-				secretNN = k8stypes.NamespacedName{Namespace: cmp.Or(ups.Spec.TLSSecret.Namespace, ar.GetNamespace()), Name: ups.Spec.TLSSecret.Name}
-			)
-			if err := r.Get(ctx, secretNN, &secret); err != nil {
-				r.Log.Error(err, "failed to get secret in ApisixUpstream", "ApisixUpstream", upsNN, "Secret", secretNN)
-				if client.IgnoreNotFound(err) != nil {
-					return err
-				}
-			}
-			tc.Secrets[secretNN] = &secret
+		if err := r.processTLSSecret(ctx, tc, ups, ar.GetNamespace()); err != nil {
+			return err
 		}
 	}
 
diff --git a/test/e2e/crds/v2/route.go b/test/e2e/crds/v2/route.go
index e9d77ed3..3e1dce56 100644
--- a/test/e2e/crds/v2/route.go
+++ b/test/e2e/crds/v2/route.go
@@ -1369,4 +1369,61 @@ spec:
 			})
 		})
 	})
+	Context("Test tls secret processed from ApisixUpstream", func() {
+		var Cert = strings.TrimSpace(framework.TestServerCert)
+		var Key = strings.TrimSpace(framework.TestServerKey)
+		createSecret := func(s *scaffold.Scaffold, secretName string) {
+			err := s.NewKubeTlsSecret(secretName, Cert, Key)
+			assert.Nil(GinkgoT(), err, "create secret error")
+		}
+		const apisixRouteSpec = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: default
+  namespace: %s
+spec:
+  ingressClassName: %s
+  http:
+  - name: rule0
+    match:
+      hosts:
+      - httpbin
+      paths:
+      - /*
+    backends:
+    - serviceName: httpbin-service-e2e-test
+      servicePort: 80
+
+`
+		const apisixUpstreamSpec = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: httpbin-service-e2e-test
+  namespace: %s
+spec:
+  ingressClassName: %s
+  tlsSecret:
+    name: %s
+    namespace: %s
+`
+
+		It("with matching backend", func() {
+			secretName := fmt.Sprintf("test-tls-secret-%s", s.Namespace())
+			createSecret(s, secretName)
+			By("apply apisixupstream")
+			applier.MustApplyAPIv2(types.NamespacedName{Namespace: s.Namespace(), Name: "httpbin-service-e2e-test"},
+				new(apiv2.ApisixUpstream), fmt.Sprintf(apisixUpstreamSpec, s.Namespace(), s.Namespace(), secretName, s.Namespace()))
+			By("apply apisixroute")
+			applier.MustApplyAPIv2(types.NamespacedName{Namespace: s.Namespace(), Name: "default"},
+				new(apiv2.ApisixRoute), fmt.Sprintf(apisixRouteSpec, s.Namespace(), s.Namespace()))
+			time.Sleep(6 * time.Second)
+			services, err := s.DefaultDataplaneResource().Service().List(context.Background())
+			Expect(err).ShouldNot(HaveOccurred(), "list services")
+			assert.Len(GinkgoT(), services, 1, "there should be one service")
+			service := services[0]
+			Expect(service.Upstream.TLS).ShouldNot(BeNil(), "check tls in service")
+		})
+	})
 })