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 1087941d fix: namespace_selector invalid when restarting (#1238)
1087941d is described below
commit 1087941d827dbf859b534328368ff8c65635db2a
Author: Xin Rong <[email protected]>
AuthorDate: Mon Aug 29 16:34:30 2022 +0800
fix: namespace_selector invalid when restarting (#1238)
---
pkg/api/validation/utils.go | 11 -
pkg/api/validation/utils_test.go | 9 -
pkg/providers/k8s/namespace/namespace_provider.go | 84 +++----
test/e2e/scaffold/ingress.go | 15 +-
test/e2e/scaffold/k8s.go | 16 +-
test/e2e/scaffold/scaffold.go | 66 ++++--
.../suite-ingress-features/namespace.go | 245 +++++++++++++++++++--
7 files changed, 337 insertions(+), 109 deletions(-)
diff --git a/pkg/api/validation/utils.go b/pkg/api/validation/utils.go
index 84180be9..5d2145cf 100644
--- a/pkg/api/validation/utils.go
+++ b/pkg/api/validation/utils.go
@@ -99,14 +99,3 @@ func validateSchema(schemaLoader *gojsonschema.JSONLoader,
obj interface{}) (boo
return false, resultErr
}
-
-func HasValueInSyncMap(m *sync.Map) bool {
- hasValue := false
- if m != nil {
- m.Range(func(k, v interface{}) bool {
- hasValue = true
- return false
- })
- }
- return hasValue
-}
diff --git a/pkg/api/validation/utils_test.go b/pkg/api/validation/utils_test.go
index 6e2c2d67..2faffe57 100644
--- a/pkg/api/validation/utils_test.go
+++ b/pkg/api/validation/utils_test.go
@@ -16,10 +16,8 @@
package validation
import (
- "sync"
"testing"
- "github.com/stretchr/testify/assert"
"github.com/xeipuuv/gojsonschema"
v2beta3
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2beta3"
@@ -48,10 +46,3 @@ func Test_validateSchema(t *testing.T) {
})
}
}
-
-func TestHasValueInSyncMap(t *testing.T) {
- m := new(sync.Map)
- assert.False(t, HasValueInSyncMap(m), "sync.Map should be empty")
- m.Store("hello", "test")
- assert.True(t, HasValueInSyncMap(m), "sync.Map should not be empty")
-}
diff --git a/pkg/providers/k8s/namespace/namespace_provider.go
b/pkg/providers/k8s/namespace/namespace_provider.go
index b4a69e92..b7915743 100644
--- a/pkg/providers/k8s/namespace/namespace_provider.go
+++ b/pkg/providers/k8s/namespace/namespace_provider.go
@@ -19,17 +19,16 @@ package namespace
import (
"context"
+ "fmt"
"strings"
"sync"
"go.uber.org/zap"
- v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
listerscorev1 "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
- "github.com/apache/apisix-ingress-controller/pkg/api/validation"
"github.com/apache/apisix-ingress-controller/pkg/config"
"github.com/apache/apisix-ingress-controller/pkg/kube"
"github.com/apache/apisix-ingress-controller/pkg/log"
@@ -48,44 +47,28 @@ type WatchingNamespaceProvider interface {
}
func NewWatchingNamespaceProvider(ctx context.Context, kube *kube.KubeClient,
cfg *config.Config) (WatchingNamespaceProvider, error) {
- var (
- watchingNamespaces = new(sync.Map)
- watchingLabels = make(map[string]string)
- )
- if len(cfg.Kubernetes.AppNamespaces) > 1 ||
cfg.Kubernetes.AppNamespaces[0] != v1.NamespaceAll {
- for _, ns := range cfg.Kubernetes.AppNamespaces {
- watchingNamespaces.Store(ns, struct{}{})
- }
+ c := &watchingProvider{
+ kube: kube,
+ cfg: cfg,
+
+ watchingNamespaces: new(sync.Map),
+ watchingLabels: make(map[string]string),
+
+ enableLabelsWatching: false,
+ }
+
+ if len(cfg.Kubernetes.NamespaceSelector) == 0 {
+ return c, nil
}
+
// support namespace label-selector
+ c.enableLabelsWatching = true
for _, selector := range cfg.Kubernetes.NamespaceSelector {
labelSlice := strings.Split(selector, "=")
- watchingLabels[labelSlice[0]] = labelSlice[1]
- }
-
- // watchingNamespaces and watchingLabels are empty means to monitor all
namespaces.
- if !validation.HasValueInSyncMap(watchingNamespaces) &&
len(watchingLabels) == 0 {
- opts := metav1.ListOptions{}
- // list all namespaces
- nsList, err := kube.Client.CoreV1().Namespaces().List(ctx, opts)
- if err != nil {
- log.Error(err.Error())
- ctx.Done()
- } else {
- wns := new(sync.Map)
- for _, v := range nsList.Items {
- wns.Store(v.Name, struct{}{})
- }
- watchingNamespaces = wns
+ if len(labelSlice) != 2 {
+ return nil, fmt.Errorf("Bad namespace-selector format:
%s, expected namespace-selector format: xxx=xxx", selector)
}
- }
-
- c := &watchingProvider{
- kube: kube,
- cfg: cfg,
-
- watchingNamespaces: watchingNamespaces,
- watchingLabels: watchingLabels,
+ c.watchingLabels[labelSlice[0]] = labelSlice[1]
}
kubeFactory := kube.NewSharedIndexInformerFactory()
@@ -108,6 +91,8 @@ type watchingProvider struct {
namespaceLister listerscorev1.NamespaceLister
controller *namespaceController
+
+ enableLabelsWatching bool
}
func (c *watchingProvider) Init(ctx context.Context) error {
@@ -138,12 +123,14 @@ func (c *watchingProvider)
initWatchingNamespacesByLabels(ctx context.Context) e
}
func (c *watchingProvider) Run(ctx context.Context) {
- e := utils.ParallelExecutor{}
+ if !c.enableLabelsWatching {
+ return
+ }
+ e := utils.ParallelExecutor{}
e.Add(func() {
c.namespaceInformer.Run(ctx.Done())
})
-
e.Add(func() {
c.controller.run(ctx)
})
@@ -153,17 +140,30 @@ func (c *watchingProvider) Run(ctx context.Context) {
func (c *watchingProvider) WatchingNamespaces() []string {
var keys []string
- c.watchingNamespaces.Range(func(key, _ interface{}) bool {
- keys = append(keys, key.(string))
- return true
- })
+ if c.enableLabelsWatching {
+ c.watchingNamespaces.Range(func(key, _ interface{}) bool {
+ keys = append(keys, key.(string))
+ return true
+ })
+ } else {
+ namespaces, err :=
c.kube.Client.CoreV1().Namespaces().List(context.Background(),
metav1.ListOptions{})
+ if err != nil {
+ log.Warnw("Namespace list get failed",
+ zap.Error(err),
+ )
+ return nil
+ }
+ for _, ns := range namespaces.Items {
+ keys = append(keys, ns.Name)
+ }
+ }
return keys
}
// IsWatchingNamespace accepts a resource key, getting the namespace part
// and checking whether the namespace is being watched.
func (c *watchingProvider) IsWatchingNamespace(key string) (ok bool) {
- if !validation.HasValueInSyncMap(c.watchingNamespaces) {
+ if !c.enableLabelsWatching {
ok = true
return
}
diff --git a/test/e2e/scaffold/ingress.go b/test/e2e/scaffold/ingress.go
index 5117e331..42ea50f1 100644
--- a/test/e2e/scaffold/ingress.go
+++ b/test/e2e/scaffold/ingress.go
@@ -428,13 +428,17 @@ func (s *Scaffold) newIngressAPISIXController() error {
})
var ingressAPISIXDeployment string
- label := fmt.Sprintf("apisix.ingress.watch=%s", s.namespace)
+ label := `""`
+ if labels := s.NamespaceSelectorLabelStrings(); labels != nil &&
!s.opts.DisableNamespaceSelector {
+ label = labels[0]
+ }
+
if s.opts.EnableWebhooks {
ingressAPISIXDeployment =
fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate),
s.opts.IngressAPISIXReplicas, s.namespace, s.opts.ApisixResourceSyncInterval,
- s.FormatNamespaceLabel(label),
s.opts.ApisixResourceVersion, s.opts.APISIXPublishAddress, _volumeMounts,
_webhookCertSecret)
+ label, s.opts.ApisixResourceVersion,
s.opts.APISIXPublishAddress, _volumeMounts, _webhookCertSecret)
} else {
ingressAPISIXDeployment =
fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate),
s.opts.IngressAPISIXReplicas, s.namespace, s.opts.ApisixResourceSyncInterval,
- s.FormatNamespaceLabel(label),
s.opts.ApisixResourceVersion, s.opts.APISIXPublishAddress, "",
_webhookCertSecret)
+ label, s.opts.ApisixResourceVersion,
s.opts.APISIXPublishAddress, "", _webhookCertSecret)
}
err = k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions,
ingressAPISIXDeployment)
@@ -538,7 +542,10 @@ func (s *Scaffold) GetIngressPodDetails() ([]corev1.Pod,
error) {
// ScaleIngressController scales the number of Ingress Controller pods to
desired.
func (s *Scaffold) ScaleIngressController(desired int) error {
var ingressDeployment string
- label := fmt.Sprintf("apisix.ingress.watch=%s", s.namespace)
+ var label string
+ if labels := s.NamespaceSelectorLabelStrings(); labels != nil {
+ label = labels[0]
+ }
if s.opts.EnableWebhooks {
ingressDeployment =
fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), desired,
s.namespace, s.opts.ApisixResourceSyncInterval, label,
s.opts.ApisixResourceVersion, s.opts.APISIXPublishAddress, _volumeMounts,
_webhookCertSecret)
} else {
diff --git a/test/e2e/scaffold/k8s.go b/test/e2e/scaffold/k8s.go
index be3689b8..23f16b76 100644
--- a/test/e2e/scaffold/k8s.go
+++ b/test/e2e/scaffold/k8s.go
@@ -161,16 +161,20 @@ func (s *Scaffold)
CreateResourceFromStringWithNamespace(yaml, namespace string)
s.kubectlOptions.Namespace = originalNamespace
}()
s.addFinalizers(func() {
- originalNamespace := s.kubectlOptions.Namespace
- s.kubectlOptions.Namespace = namespace
- defer func() {
- s.kubectlOptions.Namespace = originalNamespace
- }()
- assert.Nil(s.t, k8s.KubectlDeleteFromStringE(s.t,
s.kubectlOptions, yaml))
+ _ = s.DeleteResourceFromStringWithNamespace(yaml, namespace)
})
return k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, yaml)
}
+func (s *Scaffold) DeleteResourceFromStringWithNamespace(yaml, namespace
string) error {
+ originalNamespace := s.kubectlOptions.Namespace
+ s.kubectlOptions.Namespace = namespace
+ defer func() {
+ s.kubectlOptions.Namespace = originalNamespace
+ }()
+ return k8s.KubectlDeleteFromStringE(s.t, s.kubectlOptions, yaml)
+}
+
func (s *Scaffold) ensureNumApisixCRDsCreated(url string, desired int) error {
condFunc := func() (bool, error) {
req, err := http.NewRequest("GET", url, nil)
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index b11a33d8..11328d6c 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -54,9 +54,12 @@ type Options struct {
APISIXAdminAPIKey string
EnableWebhooks bool
APISIXPublishAddress string
- disableNamespaceSelector bool
ApisixResourceSyncInterval string
ApisixResourceVersion string
+
+ NamespaceSelectorLabel map[string]string
+ DisableNamespaceSelector bool
+ DisableNamespaceLabel bool
}
type Scaffold struct {
@@ -97,10 +100,10 @@ var (
}
createVersionedApisixResourceMap = map[string]struct{}{
- "ApisixRoute": struct{}{},
- "ApisixConsumer": struct{}{},
- "ApisixPluginConfig": struct{}{},
- "ApisixUpstream": struct{}{},
+ "ApisixRoute": {},
+ "ApisixConsumer": {},
+ "ApisixPluginConfig": {},
+ "ApisixUpstream": {},
}
)
@@ -376,6 +379,19 @@ func (s *Scaffold) RestartAPISIXDeploy() {
assert.NoError(s.t, err, "renew apisix tunnels")
}
+func (s *Scaffold) RestartIngressControllerDeploy() {
+ pods, err := k8s.ListPodsE(s.t, s.kubectlOptions, metav1.ListOptions{
+ LabelSelector:
"app=ingress-apisix-controller-deployment-e2e-test",
+ })
+ assert.NoError(s.t, err, "list ingress-controller pod")
+ for _, pod := range pods {
+ err = s.KillPod(pod.Name)
+ assert.NoError(s.t, err, "killing ingress-controller pod")
+ }
+ err = s.WaitAllIngressControllerPodsAvailable()
+ assert.NoError(s.t, err, "waiting for new ingress-controller instance
ready")
+}
+
func (s *Scaffold) beforeEach() {
var err error
s.namespace = fmt.Sprintf("ingress-apisix-e2e-tests-%s-%d",
s.opts.Name, time.Now().Nanosecond())
@@ -383,11 +399,19 @@ func (s *Scaffold) beforeEach() {
ConfigPath: s.opts.Kubeconfig,
Namespace: s.namespace,
}
-
s.finializers = nil
- labels := make(map[string]string)
- labels["apisix.ingress.watch"] = s.namespace
- k8s.CreateNamespaceWithMetadata(s.t, s.kubectlOptions,
metav1.ObjectMeta{Name: s.namespace, Labels: labels})
+
+ label := map[string]string{}
+ if !s.opts.DisableNamespaceLabel {
+ if s.opts.NamespaceSelectorLabel == nil {
+ label["apisix.ingress.watch"] = s.namespace
+ s.opts.NamespaceSelectorLabel = label
+ } else {
+ label = s.opts.NamespaceSelectorLabel
+ }
+ }
+
+ k8s.CreateNamespaceWithMetadata(s.t, s.kubectlOptions,
metav1.ObjectMeta{Name: s.namespace, Labels: label})
s.nodes, err = k8s.GetReadyNodesE(s.t, s.kubectlOptions)
assert.Nil(s.t, err, "querying ready nodes")
@@ -549,14 +573,6 @@ func (s *Scaffold) FormatRegistry(workloadTemplate string)
string {
}
}
-// FormatNamespaceLabel set label to be empty if
s.opts.disableNamespaceSelector is true.
-func (s *Scaffold) FormatNamespaceLabel(label string) string {
- if s.opts.disableNamespaceSelector {
- return "\"\""
- }
- return label
-}
-
var (
versionRegex = regexp.MustCompile(`apiVersion:
apisix.apache.org/v.*?\n`)
kindRegex = regexp.MustCompile(`kind: (.*?)\n`)
@@ -574,10 +590,6 @@ func (s *Scaffold) getKindValue(yml string) string {
return subStr[1]
}
-func (s *Scaffold) DisableNamespaceSelector() {
- s.opts.disableNamespaceSelector = true
-}
-
func waitExponentialBackoff(condFunc func() (bool, error)) error {
backoff := wait.Backoff{
Duration: 500 * time.Millisecond,
@@ -622,3 +634,15 @@ func (s *Scaffold)
CreateVersionedApisixResourceWithNamespace(yml, namespace str
func ApisixResourceVersion() *apisixResourceVersionInfo {
return apisixResourceVersion
}
+
+func (s *Scaffold) NamespaceSelectorLabelStrings() []string {
+ var labels []string
+ for k, v := range s.opts.NamespaceSelectorLabel {
+ labels = append(labels, fmt.Sprintf("%s=%s", k, v))
+ }
+ return labels
+}
+
+func (s *Scaffold) NamespaceSelectorLabel() map[string]string {
+ return s.opts.NamespaceSelectorLabel
+}
diff --git a/test/e2e/suite-ingress/suite-ingress-features/namespace.go
b/test/e2e/suite-ingress/suite-ingress-features/namespace.go
index d8e5fd74..a41b6fb4 100644
--- a/test/e2e/suite-ingress/suite-ingress-features/namespace.go
+++ b/test/e2e/suite-ingress/suite-ingress-features/namespace.go
@@ -16,6 +16,7 @@
package ingress
import (
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -24,6 +25,8 @@ import (
"github.com/gruntwork-io/terratest/modules/k8s"
ginkgo "github.com/onsi/ginkgo/v2"
"github.com/stretchr/testify/assert"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
)
@@ -37,12 +40,37 @@ type headers struct {
}
var _ = ginkgo.Describe("suite-ingress-features: namespacing filtering
enable", func() {
- s := scaffold.NewDefaultScaffold()
+ s := scaffold.NewScaffold(&scaffold.Options{
+ Name: "enable-namespace-selector",
+ IngressAPISIXReplicas: 1,
+ ApisixResourceVersion: scaffold.ApisixResourceVersion().Default,
+ NamespaceSelectorLabel: map[string]string{
+ fmt.Sprintf("namespace-selector-%d",
time.Now().Nanosecond()): "watch",
+ },
+ DisableNamespaceLabel: true,
+ })
ginkgo.Context("with namespace_selector", func() {
+ namespace1 := fmt.Sprintf("namespace-selector-1-%d",
time.Now().Nanosecond())
+ namespace2 := fmt.Sprintf("namespace-selector-2-%d",
time.Now().Nanosecond())
+
+ createNamespaceLabel := func(namespace string) {
+ k8s.CreateNamespaceWithMetadata(ginkgo.GinkgoT(),
&k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()},
metav1.ObjectMeta{Name: namespace, Labels: s.NamespaceSelectorLabel()})
+ _, err := s.NewHTTPBINWithNamespace(namespace)
+ time.Sleep(6 * time.Second)
+ assert.Nil(ginkgo.GinkgoT(), err, "create second
httpbin service")
+ }
+
+ deleteNamespace := func(namespace string) {
+ _ = k8s.DeleteNamespaceE(ginkgo.GinkgoT(),
&k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ }
+
ginkgo.It("resources in other namespaces should be ignored",
func() {
+ createNamespaceLabel(namespace1)
+ defer deleteNamespace(namespace1)
+
backendSvc, backendSvcPort := s.DefaultHTTPBackend()
- route := fmt.Sprintf(`
+ route1 := fmt.Sprintf(`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
@@ -61,17 +89,16 @@ spec:
port:
number: %d
`, backendSvc, backendSvcPort[0])
-
- assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(route), "creating ingress")
- time.Sleep(6 * time.Second)
-
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route1, namespace1), "creating ingress")
+ assert.Nil(ginkgo.GinkgoT(),
s.EnsureNumApisixRoutesCreated(1))
+ time.Sleep(time.Second * 6)
body :=
s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
var placeholder ip
err := json.Unmarshal([]byte(body), &placeholder)
assert.Nil(ginkgo.GinkgoT(), err, "unmarshalling IP")
// Now create another ingress in default namespace.
- route = fmt.Sprintf(`
+ route2 := fmt.Sprintf(`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
@@ -79,7 +106,33 @@ metadata:
spec:
ingressClassName: apisix
rules:
- - host: httpbin.com
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /headers
+ pathType: Exact
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route2, "default"), "creating ingress")
+ time.Sleep(6 * time.Second)
+ routes, err := s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 1)
+ _ =
s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.org").Expect().Status(http.StatusNotFound)
+
+ route3 := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: httpbin-route
+spec:
+ ingressClassName: apisix
+ rules:
+ - host: local.httpbin.org
http:
paths:
- path: /headers
@@ -90,18 +143,48 @@ spec:
port:
number: %d
`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(route3), "creating ingress")
+ time.Sleep(6 * time.Second)
+ routes, err = s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 1)
+ _ =
s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"local.httpbin.org").Expect().Status(http.StatusNotFound)
+
+ // remove route1
+ assert.Nil(ginkgo.GinkgoT(),
s.DeleteResourceFromStringWithNamespace(route1, namespace1), "delete ingress")
+ time.Sleep(6 * time.Second)
+
+ deleteNamespace(namespace1)
+ time.Sleep(6 * time.Second)
+ routes, err = s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
+
+ // restart ingress-controller
+ s.RestartIngressControllerDeploy()
+ time.Sleep(6 * time.Second)
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
- assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route, "default"), "creating ingress")
- _ =
s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusNotFound)
+ createNamespaceLabel(namespace2)
+ defer deleteNamespace(namespace2)
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route1, namespace2), "creating ingress")
+ assert.Nil(ginkgo.GinkgoT(),
s.EnsureNumApisixRoutesCreated(1))
+ _ = s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK)
+ _ =
s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.org").Expect().Status(http.StatusNotFound)
+ _ =
s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"local.httpbin.org").Expect().Status(http.StatusNotFound)
})
})
})
var _ = ginkgo.Describe("suite-ingress-features: namespacing filtering
disable", func() {
- s := scaffold.NewDefaultScaffold()
+ s := scaffold.NewScaffold(&scaffold.Options{
+ Name: "disable-namespace-selector",
+ IngressAPISIXReplicas: 1,
+ ApisixResourceVersion:
scaffold.ApisixResourceVersion().Default,
+ DisableNamespaceSelector: true,
+ })
ginkgo.Context("without namespace_selector", func() {
- // make namespace_selector empty
- s.DisableNamespaceSelector()
namespace := "second-httpbin-service-namespace"
// create another http-bin service in a new namespace.
@@ -110,13 +193,12 @@ var _ = ginkgo.Describe("suite-ingress-features:
namespacing filtering disable",
ConfigPath: scaffold.GetKubeconfig(),
}, namespace)
_, err := s.NewHTTPBINWithNamespace(namespace)
- assert.Nil(ginkgo.GinkgoT(), err, "create second
httpbin service")
+ assert.Nil(ginkgo.GinkgoT(), err, "create new httpbin
service")
})
// clean this tmp namespace when test case is done.
ginkgo.AfterEach(func() {
- err := k8s.DeleteNamespaceE(ginkgo.GinkgoT(),
&k8s.KubectlOptions{
- ConfigPath: scaffold.GetKubeconfig()},
namespace)
+ err := k8s.DeleteNamespaceE(ginkgo.GinkgoT(),
&k8s.KubectlOptions{ConfigPath: scaffold.GetKubeconfig()}, namespace)
assert.Nilf(ginkgo.GinkgoT(), err, "deleting namespace
%s", namespace)
})
@@ -189,3 +271,134 @@ spec:
})
})
})
+
+var _ = ginkgo.Describe("suite-ingress-features: namespacing un-label", func()
{
+ labelName, labelValue := fmt.Sprintf("namespace-selector-%d",
time.Now().Nanosecond()), "watch"
+ s := scaffold.NewScaffold(&scaffold.Options{
+ Name: "un-label",
+ IngressAPISIXReplicas: 1,
+ ApisixResourceVersion: scaffold.ApisixResourceVersion().Default,
+ NamespaceSelectorLabel: map[string]string{
+ labelName: labelValue,
+ },
+ DisableNamespaceLabel: true,
+ })
+ namespace1 := fmt.Sprintf("un-label-%d", time.Now().Nanosecond())
+
+ ginkgo.It("un-label", func() {
+ client := s.GetKubernetesClient()
+
+ ns := fmt.Sprintf(`
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: %s
+ labels:
+ %s: %s
+`, namespace1, labelName, labelValue)
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(ns, namespace1), "creating namespace")
+ //defer s.DeleteResourceFromStringWithNamespace(ns, namespace1)
+ _, err := s.NewHTTPBINWithNamespace(namespace1)
+ assert.Nil(ginkgo.GinkgoT(), err, "create httpbin service in",
namespace1)
+
+ backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+ route1 := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: httpbin-route
+spec:
+ ingressClassName: apisix
+ rules:
+ - host: httpbin.com
+ http:
+ paths:
+ - path: /ip
+ pathType: Exact
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route1, namespace1), "creating ingress")
+ assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1))
+ time.Sleep(time.Second * 6)
+ _ = s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
+
+ assert.Nil(ginkgo.GinkgoT(),
s.DeleteResourceFromStringWithNamespace(route1, namespace1), "deleting ingress")
+ // un-label
+ _, err = client.CoreV1().Namespaces().Update(
+ context.Background(),
+ &v1.Namespace{ObjectMeta: metav1.ObjectMeta{
+ Name: namespace1,
+ Labels: map[string]string{},
+ }},
+ metav1.UpdateOptions{},
+ )
+ assert.Nil(ginkgo.GinkgoT(), err, "unlabel the namespace")
+ time.Sleep(6 * time.Second)
+ routes, err := s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
+
+ route2 := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: httpbin-route
+spec:
+ ingressClassName: apisix
+ rules:
+ - host: httpbin.org
+ http:
+ paths:
+ - path: /headers
+ pathType: Exact
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(route2), "creating ingress")
+ time.Sleep(6 * time.Second)
+ routes, err = s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
+ _ = s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.org").Expect().Status(http.StatusNotFound)
+
+ route3 := fmt.Sprintf(`
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: httpbin-route
+spec:
+ ingressClassName: apisix
+ rules:
+ - host: local.httpbin.org
+ http:
+ paths:
+ - path: /headers
+ pathType: Exact
+ backend:
+ service:
+ name: %s
+ port:
+ number: %d
+`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route3, "default"), "creating ingress")
+ time.Sleep(6 * time.Second)
+ routes, err = s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
+ _ = s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"local.httpbin.org").Expect().Status(http.StatusNotFound)
+
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromStringWithNamespace(route1, namespace1), "creating ingress")
+ time.Sleep(time.Second * 6)
+ routes, err = s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), routes, 0)
+ _ = s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusNotFound)
+ })
+})