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)
+       })
+})

Reply via email to