You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by zh...@apache.org on 2022/11/04 08:58:37 UTC

[apisix-ingress-controller] branch master updated: feat: support sni based tls route (#1051)

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

zhangjintao 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 38b12fb4 feat: support sni based tls route (#1051)
38b12fb4 is described below

commit 38b12fb4a5a2169eb3585e5b7e2f78c8ce447862
Author: mango <35...@users.noreply.github.com>
AuthorDate: Fri Nov 4 16:58:30 2022 +0800

    feat: support sni based tls route (#1051)
---
 pkg/apisix/stream_route.go                         |  1 +
 pkg/apisix/stream_route_test.go                    |  6 ++
 pkg/kube/apisix/apis/config/v2/types.go            |  3 +-
 pkg/providers/apisix/translation/apisix_route.go   |  2 +
 pkg/providers/utils/manifest_test.go               |  5 ++
 samples/deploy/crd/v1/ApisixRoute.yaml             |  2 +
 .../suite-ingress/suite-ingress-resource/stream.go | 65 ++++++++++++++++++++++
 7 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/pkg/apisix/stream_route.go b/pkg/apisix/stream_route.go
index 5af306df..1d72ccd7 100644
--- a/pkg/apisix/stream_route.go
+++ b/pkg/apisix/stream_route.go
@@ -148,6 +148,7 @@ func (r *streamRouteClient) Create(ctx context.Context, obj *v1.StreamRoute) (*v
 		zap.Int32("server_port", obj.ServerPort),
 		zap.String("cluster", "default"),
 		zap.String("url", r.url),
+		zap.String("sni", obj.SNI),
 	)
 
 	if err := r.cluster.HasSynced(ctx); err != nil {
diff --git a/pkg/apisix/stream_route_test.go b/pkg/apisix/stream_route_test.go
index e1a402b2..7cc3a89c 100644
--- a/pkg/apisix/stream_route_test.go
+++ b/pkg/apisix/stream_route_test.go
@@ -164,17 +164,21 @@ func TestStreamRouteClient(t *testing.T) {
 		ID:         "1",
 		ServerPort: 8001,
 		UpstreamId: "1",
+		SNI:        "a.test.com",
 	})
 	assert.Nil(t, err)
 	assert.Equal(t, obj.ID, "1")
+	assert.Equal(t, obj.SNI, "a.test.com")
 
 	obj, err = cli.Create(context.Background(), &v1.StreamRoute{
 		ID:         "2",
 		ServerPort: 8002,
 		UpstreamId: "1",
+		SNI:        "*.test.com",
 	})
 	assert.Nil(t, err)
 	assert.Equal(t, obj.ID, "2")
+	assert.Equal(t, obj.SNI, "*.test.com")
 
 	// List
 	objs, err := cli.List(context.Background())
@@ -200,4 +204,6 @@ func TestStreamRouteClient(t *testing.T) {
 	assert.Nil(t, err)
 	assert.Len(t, objs, 1)
 	assert.Equal(t, "2", objs[0].ID)
+	assert.Equal(t, "112", objs[0].UpstreamId)
+	assert.Equal(t, "", objs[0].SNI)
 }
diff --git a/pkg/kube/apisix/apis/config/v2/types.go b/pkg/kube/apisix/apis/config/v2/types.go
index f01f57e7..0dfa089c 100644
--- a/pkg/kube/apisix/apis/config/v2/types.go
+++ b/pkg/kube/apisix/apis/config/v2/types.go
@@ -227,7 +227,8 @@ type ApisixRouteStream struct {
 type ApisixRouteStreamMatch struct {
 	// IngressPort represents the port listening on the Ingress proxy server.
 	// It should be pre-defined as APISIX doesn't support dynamic listening.
-	IngressPort int32 `json:"ingressPort" yaml:"ingressPort"`
+	IngressPort int32  `json:"ingressPort" yaml:"ingressPort"`
+	Host        string `json:"host,omitempty" yaml:"host,omitempty"`
 }
 
 // ApisixRouteStreamBackend represents a TCP backend (a Kubernetes Service).
diff --git a/pkg/providers/apisix/translation/apisix_route.go b/pkg/providers/apisix/translation/apisix_route.go
index 5a954a75..6d1de7a8 100644
--- a/pkg/providers/apisix/translation/apisix_route.go
+++ b/pkg/providers/apisix/translation/apisix_route.go
@@ -767,6 +767,7 @@ func (t *translator) translateStreamRouteV2(ctx *translation.TranslateContext, a
 		name := apisixv1.ComposeStreamRouteName(ar.Namespace, ar.Name, part.Name)
 		sr.ID = id.GenID(name)
 		sr.ServerPort = part.Match.IngressPort
+		sr.SNI = part.Match.Host
 		ups, err := t.translateService(ar.Namespace, backend.ServiceName, backend.Subset, backend.ResolveGranularity, svcClusterIP, svcPort)
 		if err != nil {
 			return err
@@ -811,6 +812,7 @@ func (t *translator) translateStreamRouteNotStrictlyV2(ctx *translation.Translat
 		name := apisixv1.ComposeStreamRouteName(ar.Namespace, ar.Name, part.Name)
 		sr.ID = id.GenID(name)
 		sr.ServerPort = part.Match.IngressPort
+		sr.SNI = part.Match.Host
 		ups, err := t.translateUpstreamNotStrictly(ar.Namespace, backend.ServiceName, backend.Subset, backend.ServicePort.IntVal, backend.ResolveGranularity)
 		if err != nil {
 			return err
diff --git a/pkg/providers/utils/manifest_test.go b/pkg/providers/utils/manifest_test.go
index d723544c..5fdcb65c 100644
--- a/pkg/providers/utils/manifest_test.go
+++ b/pkg/providers/utils/manifest_test.go
@@ -83,6 +83,7 @@ func TestDiffStreamRoutes(t *testing.T) {
 		{
 			ID:         "3",
 			ServerPort: 8080,
+			SNI:        "a.test.com",
 		},
 	}
 	added, updated, deleted := DiffStreamRoutes(nil, news)
@@ -92,6 +93,7 @@ func TestDiffStreamRoutes(t *testing.T) {
 	assert.Equal(t, "1", added[0].ID)
 	assert.Equal(t, "3", added[1].ID)
 	assert.Equal(t, int32(8080), added[1].ServerPort)
+	assert.Equal(t, "a.test.com", added[1].SNI)
 
 	olds := []*apisixv1.StreamRoute{
 		{
@@ -100,6 +102,7 @@ func TestDiffStreamRoutes(t *testing.T) {
 		{
 			ID:         "3",
 			ServerPort: 8081,
+			SNI:        "a.test.com",
 		},
 	}
 	added, updated, deleted = DiffStreamRoutes(olds, nil)
@@ -109,6 +112,7 @@ func TestDiffStreamRoutes(t *testing.T) {
 	assert.Equal(t, "2", deleted[0].ID)
 	assert.Equal(t, "3", deleted[1].ID)
 	assert.Equal(t, int32(8081), deleted[1].ServerPort)
+	assert.Equal(t, "a.test.com", deleted[1].SNI)
 
 	added, updated, deleted = DiffStreamRoutes(olds, news)
 	assert.Len(t, added, 1)
@@ -116,6 +120,7 @@ func TestDiffStreamRoutes(t *testing.T) {
 	assert.Len(t, updated, 1)
 	assert.Equal(t, "3", updated[0].ID)
 	assert.Equal(t, int32(8080), updated[0].ServerPort)
+	assert.Equal(t, "a.test.com", updated[0].SNI)
 	assert.Len(t, deleted, 1)
 	assert.Equal(t, "2", deleted[0].ID)
 }
diff --git a/samples/deploy/crd/v1/ApisixRoute.yaml b/samples/deploy/crd/v1/ApisixRoute.yaml
index a5bc2380..8ca97dc9 100644
--- a/samples/deploy/crd/v1/ApisixRoute.yaml
+++ b/samples/deploy/crd/v1/ApisixRoute.yaml
@@ -549,6 +549,8 @@ spec:
                       match:
                         type: object
                         properties:
+                          host:
+                            type: string
                           ingressPort:
                             type: integer
                             minimum: 1
diff --git a/test/e2e/suite-ingress/suite-ingress-resource/stream.go b/test/e2e/suite-ingress/suite-ingress-resource/stream.go
index a6fd1040..a6efde34 100644
--- a/test/e2e/suite-ingress/suite-ingress-resource/stream.go
+++ b/test/e2e/suite-ingress/suite-ingress-resource/stream.go
@@ -150,3 +150,68 @@ spec:
 		suites(scaffold.NewDefaultV2Scaffold())
 	})
 })
+
+var _ = ginkgo.Describe("suite-ingress-resource: ApisixRoute stream Testing SNI with v2", func() {
+	s := scaffold.NewDefaultV2Scaffold()
+
+	ginkgo.It("stream route with sni when set host", func() {
+		backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+		apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: httpbin-tcp-route
+spec:
+  stream:
+  - name: rule1
+    protocol: TCP
+    match:
+      ingressPort: 9100
+      host: a.test.com
+    backend:
+      serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+		assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(apisixRoute))
+
+		err := s.EnsureNumApisixStreamRoutesCreated(1)
+		assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+		sr, err := s.ListApisixStreamRoutes()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), sr, 1)
+		assert.Equal(ginkgo.GinkgoT(), sr[0].ServerPort, int32(9100))
+		assert.Equal(ginkgo.GinkgoT(), sr[0].SNI, "a.test.com")
+	})
+
+	ginkgo.It("no sni in stream route when not set host", func() {
+		backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+		apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: httpbin-tcp-route
+spec:
+  stream:
+  - name: rule1
+    protocol: TCP
+    match:
+      ingressPort: 9100
+    backend:
+      serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+		assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(apisixRoute))
+
+		err := s.EnsureNumApisixStreamRoutesCreated(1)
+		assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+		sr, err := s.ListApisixStreamRoutes()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), sr, 1)
+		assert.Equal(ginkgo.GinkgoT(), sr[0].ServerPort, int32(9100))
+		assert.Equal(ginkgo.GinkgoT(), sr[0].SNI, "")
+	})
+})