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 931ab069 feat: ingress annotations supports the specified upstream 
schema (#1451)
931ab069 is described below

commit 931ab0699ff1d5791484928492f101101365aee9
Author: seven dickens <[email protected]>
AuthorDate: Thu Dec 8 15:21:54 2022 +0800

    feat: ingress annotations supports the specified upstream schema (#1451)
---
 docs/en/latest/concepts/annotations.md             |  26 ++++
 pkg/providers/ingress/translation/annotations.go   |   3 +
 .../ingress/translation/annotations/types.go       |   1 +
 .../annotations/upstreamscheme/upstreamscheme.go   |  44 ++++++
 .../upstreamscheme/upstreamscheme_test.go          |  43 ++++++
 pkg/providers/ingress/translation/translator.go    |   9 ++
 pkg/types/apisix/v1/types.go                       |   7 +
 test/e2e/suite-annotations/upstreamprotocol.go     | 161 +++++++++++++++++++++
 8 files changed, 294 insertions(+)

diff --git a/docs/en/latest/concepts/annotations.md 
b/docs/en/latest/concepts/annotations.md
index d7327907..230996de 100644
--- a/docs/en/latest/concepts/annotations.md
+++ b/docs/en/latest/concepts/annotations.md
@@ -294,3 +294,29 @@ spec:
                 port:
                   number: 80
 ```
+
+## Upstream scheme
+
+The scheme used when communicating with the Upstream. this value can be one of 
'http', 'https', 'grpc', 'grpcs'. Defaults to 'http'.
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: apisix
+    k8s.apisix.apache.org/upstream-scheme: grpcs
+  name: ingress-v1
+spec:
+  rules:
+  - host: e2e.apisix.local
+    http:
+      paths:
+      - path: /helloworld.Greeter/SayHello
+        pathType: ImplementationSpecific
+        backend:
+          service:
+            name: test-backend-service-e2e-test
+            port:
+              number: 50053
+```
diff --git a/pkg/providers/ingress/translation/annotations.go 
b/pkg/providers/ingress/translation/annotations.go
index 008aab8e..b341dfc6 100644
--- a/pkg/providers/ingress/translation/annotations.go
+++ b/pkg/providers/ingress/translation/annotations.go
@@ -24,6 +24,7 @@ import (
        
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/plugins"
        
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/regex"
        
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/servicenamespace"
+       
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/upstreamscheme"
        
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/websocket"
        apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
@@ -35,6 +36,7 @@ type Ingress struct {
        EnableWebSocket  bool
        PluginConfigName string
        ServiceNamespace string
+       UpstreamScheme   string
 }
 
 var (
@@ -44,6 +46,7 @@ var (
                "EnableWebSocket":  websocket.NewParser(),
                "PluginConfigName": pluginconfig.NewParser(),
                "ServiceNamespace": servicenamespace.NewParser(),
+               "UpstreamScheme":   upstreamscheme.NewParser(),
        }
 )
 
diff --git a/pkg/providers/ingress/translation/annotations/types.go 
b/pkg/providers/ingress/translation/annotations/types.go
index 89168f55..750c7df3 100644
--- a/pkg/providers/ingress/translation/annotations/types.go
+++ b/pkg/providers/ingress/translation/annotations/types.go
@@ -26,6 +26,7 @@ const (
        AnnotationsUseRegex         = AnnotationsPrefix + "use-regex"
        AnnotationsEnableWebSocket  = AnnotationsPrefix + "enable-websocket"
        AnnotationsPluginConfigName = AnnotationsPrefix + "plugin-config-name"
+       AnnotationsUpstreamScheme   = AnnotationsPrefix + "upstream-scheme"
 )
 
 const (
diff --git 
a/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme.go
 
b/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme.go
new file mode 100644
index 00000000..2e183c4f
--- /dev/null
+++ 
b/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme.go
@@ -0,0 +1,44 @@
+// 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 upstreamscheme
+
+import (
+       "fmt"
+       "strings"
+
+       
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations"
+       apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+)
+
+type upstreamscheme struct{}
+
+func NewParser() annotations.IngressAnnotationsParser {
+       return &upstreamscheme{}
+}
+
+func (w *upstreamscheme) Parse(e annotations.Extractor) (interface{}, error) {
+       scheme := 
strings.ToLower(e.GetStringAnnotation(annotations.AnnotationsUpstreamScheme))
+       _, ok := apisixv1.ValidSchemes[scheme]
+       if ok {
+               return scheme, nil
+       }
+
+       keys := make([]string, 0, len(apisixv1.ValidSchemes))
+       for key := range apisixv1.ValidSchemes {
+               keys = append(keys, key)
+       }
+
+       return nil, fmt.Errorf("scheme %s is not supported, Only { %s } are 
supported", scheme, strings.Join(keys, ", "))
+}
diff --git 
a/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme_test.go
 
b/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme_test.go
new file mode 100644
index 00000000..1a762109
--- /dev/null
+++ 
b/pkg/providers/ingress/translation/annotations/upstreamscheme/upstreamscheme_test.go
@@ -0,0 +1,43 @@
+// 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 upstreamscheme
+
+import (
+       "testing"
+
+       
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestIPRestrictionHandler(t *testing.T) {
+       anno := map[string]string{
+               annotations.AnnotationsUpstreamScheme: "grpcs",
+       }
+       u := NewParser()
+
+       out, err := u.Parse(annotations.NewExtractor(anno))
+       assert.Nil(t, err, "checking given error")
+       assert.Equal(t, "grpcs", out)
+
+       anno[annotations.AnnotationsUpstreamScheme] = "gRPC"
+       out, err = u.Parse(annotations.NewExtractor(anno))
+       assert.Nil(t, err, "checking given error")
+       assert.Equal(t, "grpc", out)
+
+       anno[annotations.AnnotationsUpstreamScheme] = "nothing"
+       out, err = u.Parse(annotations.NewExtractor(anno))
+       assert.NotNil(t, err, "checking given error")
+       assert.Nil(t, out, "checking given output")
+}
diff --git a/pkg/providers/ingress/translation/translator.go 
b/pkg/providers/ingress/translation/translator.go
index c5441af4..4a6e05ff 100644
--- a/pkg/providers/ingress/translation/translator.go
+++ b/pkg/providers/ingress/translation/translator.go
@@ -162,6 +162,9 @@ func (t *translator) translateIngressV1(ing 
*networkingv1.Ingress, skipVerify bo
                                                return nil, err
                                        }
                                }
+                               if ingress.UpstreamScheme != "" {
+                                       ups.Scheme = ingress.UpstreamScheme
+                               }
                                ctx.AddUpstream(ups)
                        }
                        uris := []string{pathRule.Path}
@@ -264,6 +267,9 @@ func (t *translator) translateIngressV1beta1(ing 
*networkingv1beta1.Ingress, ski
                                                return nil, err
                                        }
                                }
+                               if ingress.UpstreamScheme != "" {
+                                       ups.Scheme = ingress.UpstreamScheme
+                               }
                                ctx.AddUpstream(ups)
                        }
                        uris := []string{pathRule.Path}
@@ -421,6 +427,9 @@ func (t *translator) translateIngressExtensionsV1beta1(ing 
*extensionsv1beta1.In
                                                return nil, err
                                        }
                                }
+                               if ingress.UpstreamScheme != "" {
+                                       ups.Scheme = ingress.UpstreamScheme
+                               }
                                ctx.AddUpstream(ups)
                        }
                        uris := []string{pathRule.Path}
diff --git a/pkg/types/apisix/v1/types.go b/pkg/types/apisix/v1/types.go
index 36caa318..cf7a2618 100644
--- a/pkg/types/apisix/v1/types.go
+++ b/pkg/types/apisix/v1/types.go
@@ -81,6 +81,13 @@ const (
        DefaultUpstreamTimeout = 60
 )
 
+var ValidSchemes map[string]struct{} = map[string]struct{}{
+       SchemeHTTP:  {},
+       SchemeHTTPS: {},
+       SchemeGRPC:  {},
+       SchemeGRPCS: {},
+}
+
 // Metadata contains all meta information about resources.
 // +k8s:deepcopy-gen=true
 type Metadata struct {
diff --git a/test/e2e/suite-annotations/upstreamprotocol.go 
b/test/e2e/suite-annotations/upstreamprotocol.go
new file mode 100644
index 00000000..a8d7bd4a
--- /dev/null
+++ b/test/e2e/suite-annotations/upstreamprotocol.go
@@ -0,0 +1,161 @@
+// 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 annotations
+
+import (
+       "time"
+
+       ginkgo "github.com/onsi/ginkgo/v2"
+       "github.com/stretchr/testify/assert"
+
+       "github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("suite-annotations: annotations.networking/v1 upstream 
scheme", func() {
+       s := scaffold.NewDefaultScaffold()
+       ginkgo.It("sanity", func() {
+               ing := `
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: apisix
+    k8s.apisix.apache.org/upstream-scheme: grpcs
+  name: ingress-v1
+spec:
+  rules:
+  - host: e2e.apisix.local
+    http:
+      paths:
+      - path: /helloworld.Greeter/SayHello
+        pathType: ImplementationSpecific
+        backend:
+          service:
+            name: test-backend-service-e2e-test
+            port:
+              number: 50053
+`
+               assert.NoError(ginkgo.GinkgoT(), 
s.CreateResourceFromString(ing))
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               time.Sleep(2 * time.Second)
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].Scheme, "grpcs")
+       })
+})
+
+var _ = ginkgo.Describe("suite-annotations-error: annotations.networking/v1 
upstream scheme error", func() {
+       s := scaffold.NewDefaultScaffold()
+       ginkgo.It("sanity", func() {
+               ing := `
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: apisix
+    k8s.apisix.apache.org/upstream-scheme: nothing
+  name: ingress-v1
+spec:
+  rules:
+  - host: e2e.apisix.local
+    http:
+      paths:
+      - path: /helloworld.Greeter/SayHello
+        pathType: ImplementationSpecific
+        backend:
+          service:
+            name: test-backend-service-e2e-test
+            port:
+              number: 50053
+`
+               assert.NoError(ginkgo.GinkgoT(), 
s.CreateResourceFromString(ing))
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               time.Sleep(2 * time.Second)
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].Scheme, "http")
+       })
+})
+
+var _ = ginkgo.Describe("suite-annotations: annotations.networking/v1beta1 
upstream scheme", func() {
+       s := scaffold.NewDefaultScaffold()
+       ginkgo.It("sanity", func() {
+               ing := `
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+  name: ingress-v1beta1
+  annotations:
+    kubernetes.io/ingress.class: apisix
+    k8s.apisix.apache.org/upstream-scheme: grpcs
+spec:
+  rules:
+  - host: e2e.apisix.local
+    http:
+      paths:
+      - path: /helloworld.Greeter/SayHello
+        pathType: ImplementationSpecific
+        backend:
+          serviceName: test-backend-service-e2e-test
+          servicePort: 50053
+`
+               assert.NoError(ginkgo.GinkgoT(), 
s.CreateResourceFromString(ing))
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               time.Sleep(2 * time.Second)
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].Scheme, "grpcs")
+       })
+})
+
+var _ = ginkgo.Describe("suite-annotations: annotations.extensions/v1beta1 
upstream scheme", func() {
+       s := scaffold.NewDefaultScaffold()
+       ginkgo.It("sanity", func() {
+               ing := `
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: apisix
+    k8s.apisix.apache.org/upstream-scheme: grpcs
+  name: ingress-ext-v1beta1
+spec:
+  rules:
+  - host: e2e.apisix.local
+    http:
+      paths:
+      - path: /helloworld.Greeter/SayHello
+        pathType: ImplementationSpecific
+        backend:
+          serviceName: test-backend-service-e2e-test
+          servicePort: 50053
+`
+               assert.NoError(ginkgo.GinkgoT(), 
s.CreateResourceFromString(ing))
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               time.Sleep(2 * time.Second)
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].Scheme, "grpcs")
+       })
+})

Reply via email to