You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by to...@apache.org on 2021/02/03 09:28:56 UTC

[apisix-ingress-controller] branch master updated: chore: support grpc scheme in ApisixUpstream (#222)

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

tokers 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 c786e08  chore: support grpc scheme in ApisixUpstream (#222)
c786e08 is described below

commit c786e083d3dc9bc4b1e8c2e2b9e7a099da6c88e5
Author: Alex Zhang <zc...@gmail.com>
AuthorDate: Wed Feb 3 17:28:49 2021 +0800

    chore: support grpc scheme in ApisixUpstream (#222)
---
 go.sum                                  |   2 +
 pkg/apisix/resource.go                  |  16 ++---
 pkg/apisix/upstream.go                  |   3 +
 pkg/ingress/apisix/upstream.go          |   8 +++
 pkg/ingress/controller/endpoint.go      |   4 +-
 pkg/kube/apisix/apis/config/v1/types.go |  11 ++++
 pkg/types/apisix/v1/types.go            |   1 +
 test/e2e/e2e.go                         |   1 +
 test/e2e/features/scheme.go             | 112 ++++++++++++++++++++++++++++++++
 test/e2e/go.mod                         |   1 +
 test/e2e/go.sum                         |   2 +
 test/e2e/ingress/namespace.go           |   3 +-
 test/e2e/ingress/sanity.go              |   3 +-
 test/e2e/scaffold/scaffold.go           |   5 ++
 14 files changed, 159 insertions(+), 13 deletions(-)

diff --git a/go.sum b/go.sum
index d45702a..670ae5c 100644
--- a/go.sum
+++ b/go.sum
@@ -613,6 +613,7 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4
 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -620,6 +621,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff --git a/pkg/apisix/resource.go b/pkg/apisix/resource.go
index bb4db43..27f8589 100644
--- a/pkg/apisix/resource.go
+++ b/pkg/apisix/resource.go
@@ -126,11 +126,6 @@ func (i *item) upstream(clusterName string) (*v1.Upstream, error) {
 		return nil, err
 	}
 
-	id := list[len(list)-1]
-	name := ups.Desc
-	LBType := ups.LBType
-	key := i.Key
-
 	var nodes []v1.Node
 	for _, node := range ups.Nodes {
 		nodes = append(nodes, v1.Node{
@@ -144,14 +139,15 @@ func (i *item) upstream(clusterName string) (*v1.Upstream, error) {
 
 	return &v1.Upstream{
 		Metadata: v1.Metadata{
-			ID:       id,
+			ID:       list[len(list)-1],
 			FullName: fullName,
 			Group:    clusterName,
-			Name:     name,
+			Name:     ups.Desc,
 		},
-		Type:  LBType,
-		Key:   key,
-		Nodes: nodes,
+		Type:   ups.LBType,
+		Key:    i.Key,
+		Nodes:  nodes,
+		Scheme: ups.Scheme,
 	}, nil
 }
 
diff --git a/pkg/apisix/upstream.go b/pkg/apisix/upstream.go
index 5e10c60..ba6503b 100644
--- a/pkg/apisix/upstream.go
+++ b/pkg/apisix/upstream.go
@@ -67,12 +67,14 @@ type upstreamReqBody struct {
 	Key    string        `json:"key,omitempty"`
 	Nodes  upstreamNodes `json:"nodes"`
 	Desc   string        `json:"desc"`
+	Scheme string        `json:"scheme,omitempty"`
 }
 
 type upstreamItem struct {
 	Nodes  upstreamNodes `json:"nodes"`
 	Desc   string        `json:"desc"`
 	LBType string        `json:"type"`
+	Scheme string        `json:"scheme"`
 }
 
 func newUpstreamClient(c *cluster) Upstream {
@@ -199,6 +201,7 @@ func (u *upstreamClient) Create(ctx context.Context, obj *v1.Upstream) (*v1.Upst
 		Key:    obj.Key,
 		Nodes:  nodes,
 		Desc:   obj.Name,
+		Scheme: obj.Scheme,
 	})
 	if err != nil {
 		return nil, err
diff --git a/pkg/ingress/apisix/upstream.go b/pkg/ingress/apisix/upstream.go
index 31b6da3..a5970e6 100644
--- a/pkg/ingress/apisix/upstream.go
+++ b/pkg/ingress/apisix/upstream.go
@@ -16,6 +16,7 @@ package apisix
 
 import (
 	"errors"
+	"fmt"
 	"strconv"
 
 	"github.com/apache/apisix-ingress-controller/pkg/ingress/endpoint"
@@ -48,6 +49,10 @@ func (aub *ApisixUpstreamBuilder) Convert() ([]*apisix.Upstream, error) {
 	rv := ar.ObjectMeta.ResourceVersion
 	Ports := ar.Spec.Ports
 	for _, r := range Ports {
+		if r.Scheme != "" && r.Scheme != configv1.SchemeHTTP && r.Scheme != configv1.SchemeGRPC {
+			return nil, fmt.Errorf("bad scheme %s", r.Scheme)
+		}
+
 		port := r.Port
 		// apisix route name = namespace_svcName_svcPort = apisix service name
 		apisixUpstreamName := ns + "_" + name + "_" + strconv.Itoa(int(port))
@@ -73,6 +78,9 @@ func (aub *ApisixUpstreamBuilder) Convert() ([]*apisix.Upstream, error) {
 			Nodes:    nodes,
 			FromKind: fromKind,
 		}
+		if r.Scheme != "" {
+			upstream.Scheme = r.Scheme
+		}
 		if lb == nil || lb.Type == "" {
 			upstream.Type = apisix.LbRoundRobin
 		} else {
diff --git a/pkg/ingress/controller/endpoint.go b/pkg/ingress/controller/endpoint.go
index a0f4f12..c2937d6 100644
--- a/pkg/ingress/controller/endpoint.go
+++ b/pkg/ingress/controller/endpoint.go
@@ -172,7 +172,9 @@ func (c *endpointsController) handleSyncErr(obj interface{}, err error) {
 		return
 	}
 	if c.workqueue.NumRequeues(obj) < _maxRetries {
-		log.Infof("sync endpoints %+v failed, will retry", obj)
+		log.Infow("sync endpoints failed, will retry",
+			zap.Any("object", obj),
+		)
 		c.workqueue.AddRateLimited(obj)
 	} else {
 		c.workqueue.Forget(obj)
diff --git a/pkg/kube/apisix/apis/config/v1/types.go b/pkg/kube/apisix/apis/config/v1/types.go
index f60c1cc..5b58e96 100644
--- a/pkg/kube/apisix/apis/config/v1/types.go
+++ b/pkg/kube/apisix/apis/config/v1/types.go
@@ -91,8 +91,19 @@ type ApisixUpstreamSpec struct {
 type Port struct {
 	Port         int           `json:"port,omitempty"`
 	LoadBalancer *LoadBalancer `json:"loadbalancer,omitempty"`
+	// The scheme used to talk with the upstream.
+	// Now value can be http, grpc.
+	// +optional
+	Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
 }
 
+var (
+	// SchemeHTTP represents the HTTP protocol.
+	SchemeHTTP = "http"
+	// SchemeGRPC represents the GRPC protocol.
+	SchemeGRPC = "grpc"
+)
+
 // LoadBalancer describes the load balancing parameters.
 type LoadBalancer struct {
 	Type string `json:"type" yaml:"type"`
diff --git a/pkg/types/apisix/v1/types.go b/pkg/types/apisix/v1/types.go
index 9b0b13a..4354be4 100644
--- a/pkg/types/apisix/v1/types.go
+++ b/pkg/types/apisix/v1/types.go
@@ -106,6 +106,7 @@ type Upstream struct {
 	Key      string `json:"key,omitempty" yaml:"key,omitempty"`
 	Nodes    []Node `json:"nodes,omitempty" yaml:"nodes,omitempty"`
 	FromKind string `json:"from_kind,omitempty" yaml:"from_kind,omitempty"`
+	Scheme   string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
 }
 
 // Node the node in upstream
diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go
index 9640ef8..8c5052d 100644
--- a/test/e2e/e2e.go
+++ b/test/e2e/e2e.go
@@ -16,6 +16,7 @@ package e2e
 
 import (
 	_ "github.com/apache/apisix-ingress-controller/test/e2e/endpoints"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/features"
 	_ "github.com/apache/apisix-ingress-controller/test/e2e/ingress"
 )
 
diff --git a/test/e2e/features/scheme.go b/test/e2e/features/scheme.go
new file mode 100644
index 0000000..6e50e2c
--- /dev/null
+++ b/test/e2e/features/scheme.go
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package features
+
+import (
+	"time"
+
+	"github.com/onsi/ginkgo"
+	"github.com/stretchr/testify/assert"
+
+	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("choose scheme", func() {
+	s := scaffold.NewDefaultScaffold()
+	ginkgo.It("grpc", func() {
+		err := s.CreateResourceFromString(`
+apiVersion: v1
+kind: Pod
+metadata:
+  name: grpc-server
+  labels:
+    app: grpc-server
+spec:
+  containers:
+  - name: grcp-server
+    image: docker.io/tokers/grpc_server_example:latest
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: grpc-server-service
+spec:
+  selector:
+    app: grpc-server
+  ports:
+  - name: grpc
+    port: 50051
+    protocol: TCP
+    targetPort: 50051
+`)
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(`
+apiVersion: apisix.apache.org/v1
+kind: ApisixUpstream
+metadata:
+  name: grpc-server-service
+spec:
+  ports:
+    - port: 50051
+      scheme: grpc
+`))
+		time.Sleep(2 * time.Second)
+		ups, err := s.ListApisixUpstreams()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), ups, 1)
+
+		err = s.CreateResourceFromString(`
+apiVersion: apisix.apache.org/v1
+kind: ApisixRoute
+metadata:
+ name: grpc-route
+spec:
+ rules:
+ - host: grpc.local
+   http:
+     paths:
+     - backend:
+         serviceName: grpc-server-service
+         servicePort: 50051
+       path: /helloworld.Greeter/SayHello
+`)
+		assert.Nil(ginkgo.GinkgoT(), err)
+
+		// TODO enable the following test cases once APISIX supports HTTP/2 in plain.
+		//ep, err := s.GetAPISIXEndpoint()
+		//assert.Nil(ginkgo.GinkgoT(), err)
+		//ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+		//defer cancel()
+		//dialFunc := func(ctx context.Context, addr string) (net.Conn, error) {
+		//	return (&net.Dialer{}).DialContext(ctx, "tcp", addr)
+		//}
+		//
+		//grpcConn, err := grpc.DialContext(ctx, ep,
+		//	grpc.WithBlock(),
+		//	grpc.WithInsecure(),
+		//	grpc.WithContextDialer(dialFunc),
+		//)
+		//assert.Nil(ginkgo.GinkgoT(), err)
+		//defer grpcConn.Close()
+		//cli := helloworld.NewGreeterClient(grpcConn)
+		//hr := &helloworld.HelloRequest{
+		//	Name: "Alex",
+		//}
+		//resp, err := cli.SayHello(context.TODO(), hr)
+		//assert.Nil(ginkgo.GinkgoT(), err)
+		//assert.Equal(ginkgo.GinkgoT(), resp.Message, "Alex")
+	})
+})
diff --git a/test/e2e/go.mod b/test/e2e/go.mod
index 410a084..68e421b 100644
--- a/test/e2e/go.mod
+++ b/test/e2e/go.mod
@@ -8,6 +8,7 @@ require (
 	github.com/gruntwork-io/terratest v0.31.2
 	github.com/onsi/ginkgo v1.14.2
 	github.com/stretchr/testify v1.6.1
+	google.golang.org/grpc v1.27.1
 	k8s.io/api v0.20.2
 	k8s.io/apimachinery v0.20.2
 )
diff --git a/test/e2e/go.sum b/test/e2e/go.sum
index bd5bae6..f8e48f6 100644
--- a/test/e2e/go.sum
+++ b/test/e2e/go.sum
@@ -835,6 +835,7 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4
 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -844,6 +845,7 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
 google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff --git a/test/e2e/ingress/namespace.go b/test/e2e/ingress/namespace.go
index b2868fe..9f4d1f9 100644
--- a/test/e2e/ingress/namespace.go
+++ b/test/e2e/ingress/namespace.go
@@ -21,9 +21,10 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 	"github.com/onsi/ginkgo"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
 var _ = ginkgo.Describe("namespacing filtering", func() {
diff --git a/test/e2e/ingress/sanity.go b/test/e2e/ingress/sanity.go
index d31884d..009efb3 100644
--- a/test/e2e/ingress/sanity.go
+++ b/test/e2e/ingress/sanity.go
@@ -19,9 +19,10 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 	"github.com/onsi/ginkgo"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
 type ip struct {
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index 6e3e851..18bee6d 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -129,6 +129,11 @@ func (s *Scaffold) DefaultHTTPBackend() (string, []int32) {
 	return s.httpbinService.Name, ports
 }
 
+// GetAPISIXEndpoint returns the service and port (as an endpoint).
+func (s *Scaffold) GetAPISIXEndpoint() (string, error) {
+	return s.apisixServiceURL()
+}
+
 // NewAPISIXClient creates the default HTTP client.
 func (s *Scaffold) NewAPISIXClient() *httpexpect.Expect {
 	host, err := s.apisixServiceURL()