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()