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/12/08 07:21:59 UTC
[apisix-ingress-controller] branch master updated: feat: ingress annotations supports the specified upstream schema (#1451)
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 <la...@163.com>
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")
+ })
+})