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/01 06:28:48 UTC
[apisix-ingress-controller] branch master updated: feat: support ingress and backend service in different namespace (#1377)
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 6879c81f feat: support ingress and backend service in different namespace (#1377)
6879c81f is described below
commit 6879c81fa5768db13e566d86b85f1c1fe9cf4073
Author: 林靖 <56...@qq.com>
AuthorDate: Tue Nov 1 14:28:42 2022 +0800
feat: support ingress and backend service in different namespace (#1377)
---
pkg/providers/ingress/translation/annotations.go | 3 +
.../servicenamespace/servicenamespace.go | 29 +
.../ingress/translation/annotations/types.go | 3 +
.../ingress/translation/annotations_test.go | 9 +
pkg/providers/ingress/translation/translator.go | 24 +-
test/e2e/suite-annotations/svc_namespace.go | 628 +++++++++++++++++++++
6 files changed, 690 insertions(+), 6 deletions(-)
diff --git a/pkg/providers/ingress/translation/annotations.go b/pkg/providers/ingress/translation/annotations.go
index 6bedd91e..008aab8e 100644
--- a/pkg/providers/ingress/translation/annotations.go
+++ b/pkg/providers/ingress/translation/annotations.go
@@ -23,6 +23,7 @@ import (
"github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations/pluginconfig"
"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/websocket"
apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
)
@@ -33,6 +34,7 @@ type Ingress struct {
UseRegex bool
EnableWebSocket bool
PluginConfigName string
+ ServiceNamespace string
}
var (
@@ -41,6 +43,7 @@ var (
"UseRegex": regex.NewParser(),
"EnableWebSocket": websocket.NewParser(),
"PluginConfigName": pluginconfig.NewParser(),
+ "ServiceNamespace": servicenamespace.NewParser(),
}
)
diff --git a/pkg/providers/ingress/translation/annotations/servicenamespace/servicenamespace.go b/pkg/providers/ingress/translation/annotations/servicenamespace/servicenamespace.go
new file mode 100644
index 00000000..e7790705
--- /dev/null
+++ b/pkg/providers/ingress/translation/annotations/servicenamespace/servicenamespace.go
@@ -0,0 +1,29 @@
+// 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 servicenamespace
+
+import (
+ "github.com/apache/apisix-ingress-controller/pkg/providers/ingress/translation/annotations"
+)
+
+type servicenamespace struct{}
+
+func NewParser() annotations.IngressAnnotationsParser {
+ return &servicenamespace{}
+}
+
+func (w *servicenamespace) Parse(e annotations.Extractor) (interface{}, error) {
+ return e.GetStringAnnotation(annotations.AnnotationsSvcNamespace), nil
+}
diff --git a/pkg/providers/ingress/translation/annotations/types.go b/pkg/providers/ingress/translation/annotations/types.go
index 66ea36e4..f23cc6e7 100644
--- a/pkg/providers/ingress/translation/annotations/types.go
+++ b/pkg/providers/ingress/translation/annotations/types.go
@@ -65,6 +65,9 @@ const (
// key-auth plugin and basic-auth plugin
// auth-type: keyAuth | basicAuth
AnnotationsAuthType = AnnotationsPrefix + "auth-type"
+
+ // support backend service cross namespace
+ AnnotationsSvcNamespace = AnnotationsPrefix + "svc-namespace"
)
// Handler abstracts the behavior so that the apisix-ingress-controller knows
diff --git a/pkg/providers/ingress/translation/annotations_test.go b/pkg/providers/ingress/translation/annotations_test.go
index 4bf11e1d..a4b80741 100644
--- a/pkg/providers/ingress/translation/annotations_test.go
+++ b/pkg/providers/ingress/translation/annotations_test.go
@@ -72,3 +72,12 @@ func TestAnnotationsUseRegex(t *testing.T) {
ingress := (&translator{}).TranslateAnnotations(anno)
assert.Equal(t, true, ingress.UseRegex)
}
+
+func TestAnnotationsServiceNamespace(t *testing.T) {
+ anno := map[string]string{
+ annotations.AnnotationsSvcNamespace: "mynamespace",
+ }
+
+ ingress := (&translator{}).TranslateAnnotations(anno)
+ assert.Equal(t, "mynamespace", ingress.ServiceNamespace)
+}
diff --git a/pkg/providers/ingress/translation/translator.go b/pkg/providers/ingress/translation/translator.go
index 6f709796..c5441af4 100644
--- a/pkg/providers/ingress/translation/translator.go
+++ b/pkg/providers/ingress/translation/translator.go
@@ -139,6 +139,10 @@ func (t *translator) translateIngressV1(ing *networkingv1.Ingress, skipVerify bo
}
ctx.AddSSL(ssl)
}
+ ns := ing.Namespace
+ if ingress.ServiceNamespace != "" {
+ ns = ingress.ServiceNamespace
+ }
for _, rule := range ing.Spec.Rules {
for _, pathRule := range rule.HTTP.Paths {
var (
@@ -147,9 +151,9 @@ func (t *translator) translateIngressV1(ing *networkingv1.Ingress, skipVerify bo
)
if pathRule.Backend.Service != nil {
if skipVerify {
- ups = t.translateDefaultUpstreamFromIngressV1(ing.Namespace, pathRule.Backend.Service)
+ ups = t.translateDefaultUpstreamFromIngressV1(ns, pathRule.Backend.Service)
} else {
- ups, err = t.translateUpstreamFromIngressV1(ing.Namespace, pathRule.Backend.Service)
+ ups, err = t.translateUpstreamFromIngressV1(ns, pathRule.Backend.Service)
if err != nil {
log.Errorw("failed to translate ingress backend to upstream",
zap.Error(err),
@@ -237,6 +241,10 @@ func (t *translator) translateIngressV1beta1(ing *networkingv1beta1.Ingress, ski
}
ctx.AddSSL(ssl)
}
+ ns := ing.Namespace
+ if ingress.ServiceNamespace != "" {
+ ns = ingress.ServiceNamespace
+ }
for _, rule := range ing.Spec.Rules {
for _, pathRule := range rule.HTTP.Paths {
var (
@@ -245,9 +253,9 @@ func (t *translator) translateIngressV1beta1(ing *networkingv1beta1.Ingress, ski
)
if pathRule.Backend.ServiceName != "" {
if skipVerify {
- ups = t.translateDefaultUpstreamFromIngressV1beta1(ing.Namespace, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+ ups = t.translateDefaultUpstreamFromIngressV1beta1(ns, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
} else {
- ups, err = t.translateUpstreamFromIngressV1beta1(ing.Namespace, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+ ups, err = t.translateUpstreamFromIngressV1beta1(ns, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
if err != nil {
log.Errorw("failed to translate ingress backend to upstream",
zap.Error(err),
@@ -389,6 +397,10 @@ func (t *translator) translateIngressExtensionsV1beta1(ing *extensionsv1beta1.In
}
ctx.AddSSL(ssl)
}
+ ns := ing.Namespace
+ if ingress.ServiceNamespace != "" {
+ ns = ingress.ServiceNamespace
+ }
for _, rule := range ing.Spec.Rules {
for _, pathRule := range rule.HTTP.Paths {
var (
@@ -398,9 +410,9 @@ func (t *translator) translateIngressExtensionsV1beta1(ing *extensionsv1beta1.In
if pathRule.Backend.ServiceName != "" {
// Structure here is same to ingress.extensions/v1beta1, so just use this method.
if skipVerify {
- ups = t.translateDefaultUpstreamFromIngressV1beta1(ing.Namespace, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+ ups = t.translateDefaultUpstreamFromIngressV1beta1(ns, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
} else {
- ups, err = t.translateUpstreamFromIngressV1beta1(ing.Namespace, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+ ups, err = t.translateUpstreamFromIngressV1beta1(ns, pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
if err != nil {
log.Errorw("failed to translate ingress backend to upstream",
zap.Error(err),
diff --git a/test/e2e/suite-annotations/svc_namespace.go b/test/e2e/suite-annotations/svc_namespace.go
new file mode 100644
index 00000000..f2797ed6
--- /dev/null
+++ b/test/e2e/suite-annotations/svc_namespace.go
@@ -0,0 +1,628 @@
+// 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 (
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/gruntwork-io/terratest/modules/k8s"
+ ginkgo "github.com/onsi/ginkgo/v2"
+ "github.com/stretchr/testify/assert"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ "github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+
+ s := scaffold.NewDefaultV2beta3Scaffold()
+
+ ginkgo.It("same namespace in ingress networking/v1", func() {
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ name: ingress-v1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendPort[0])
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+ s := scaffold.NewDefaultV2beta3Scaffold()
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress networking/v1", func() {
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-v1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, oldNs, backendSvc, backendPort[0])
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+
+ s := scaffold.NewDefaultV2beta3Scaffold()
+ ginkgo.It("same namespace in ingress networking/v1beta1", func() {
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: ""
+ name: ingress-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendPort[0])
+
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+ s := scaffold.NewDefaultV2beta3Scaffold()
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress networking/v1beta1", func() {
+
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, oldNs, backendSvc, backendPort[0])
+
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+ s := scaffold.NewDefaultV2beta3Scaffold()
+
+ ginkgo.It("same namespace in ingress extensions/v1beta1", func() {
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ name: ingress-extensions-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendPort[0])
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2beta3", func() {
+ s := scaffold.NewDefaultV2beta3Scaffold()
+
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress extensions/v1beta1", func() {
+
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-extensions-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, oldNs, backendSvc, backendPort[0])
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+
+ s := scaffold.NewDefaultV2Scaffold()
+
+ ginkgo.It("same namespace in ingress networking/v1", func() {
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ name: ingress-v1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendPort[0])
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+ s := scaffold.NewDefaultV2Scaffold()
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress networking/v1", func() {
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-v1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, oldNs, backendSvc, backendPort[0])
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+
+ s := scaffold.NewDefaultV2Scaffold()
+ ginkgo.It("same namespace in ingress networking/v1beta1", func() {
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: ""
+ name: ingress-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendPort[0])
+
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+ s := scaffold.NewDefaultV2Scaffold()
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress networking/v1beta1", func() {
+
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, oldNs, backendSvc, backendPort[0])
+
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+ s := scaffold.NewDefaultV2Scaffold()
+
+ ginkgo.It("same namespace in ingress extensions/v1beta1", func() {
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ name: ingress-extensions-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendPort[0])
+ err := s.CreateResourceFromString(ing)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})
+
+var _ = ginkgo.Describe("suite-annotations: svc-namespace annotations v2", func() {
+ s := scaffold.NewDefaultV2Scaffold()
+
+ createNamespace := func(namespace string, watch string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
+ &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
+ metav1.ObjectMeta{Name: namespace, Labels: map[string]string{
+ "apisix.ingress.watch": watch,
+ }})
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
+ ginkgo.It("different namespace in ingress extensions/v1beta1", func() {
+
+ newNs := fmt.Sprintf("second-svc-namespace-%d", time.Now().Nanosecond())
+ oldNs := s.Namespace()
+ createNamespace(newNs, oldNs)
+ defer deleteNamespace(newNs)
+
+ backendSvc, backendPort := s.DefaultHTTPBackend()
+ ing := fmt.Sprintf(`
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: apisix
+ k8s.apisix.apache.org/svc-namespace: %s
+ name: ingress-extensions-v1beta1
+spec:
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /*
+ pathType: Prefix
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, oldNs, backendSvc, backendPort[0])
+ err := s.CreateResourceFromStringWithNamespace(ing, newNs)
+ if err != nil {
+ assert.Fail(ginkgo.GinkgoT(), err.Error(), "creating ingress")
+ }
+ time.Sleep(5 * time.Second)
+
+ _ = s.NewAPISIXClient().
+ POST("/anything").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusOK).
+ Body().
+ Raw()
+ })
+})