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/03/23 03:29:21 UTC
[apisix-ingress-controller] branch master updated: fix: watch all namespaces by default (#919)
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 0a66151 fix: watch all namespaces by default (#919)
0a66151 is described below
commit 0a66151853b2e0ee1d9c43af62f144f9dc63a688
Author: cmssczy <ca...@cmss.chinamobile.com>
AuthorDate: Wed Mar 23 11:29:16 2022 +0800
fix: watch all namespaces by default (#919)
---
pkg/ingress/compare.go | 5 +-
pkg/ingress/namespace.go | 8 +--
test/e2e/ingress/namespace.go | 130 +++++++++++++++++++++++++++++++++++++-----
test/e2e/ingress/sanity.go | 5 +-
test/e2e/scaffold/httpbin.go | 9 +++
test/e2e/scaffold/ingress.go | 9 +--
test/e2e/scaffold/scaffold.go | 33 +++++++----
7 files changed, 162 insertions(+), 37 deletions(-)
diff --git a/pkg/ingress/compare.go b/pkg/ingress/compare.go
index 05c7521..c689e91 100644
--- a/pkg/ingress/compare.go
+++ b/pkg/ingress/compare.go
@@ -46,8 +46,8 @@ func (c *Controller) CompareResources(ctx context.Context) error {
consumerMapA6 = make(map[string]string)
pluginConfigMapA6 = make(map[string]string)
)
- // watchingNamespaces == nil means to monitor all namespaces
- if !validation.HasValueInSyncMap(c.watchingNamespaces) {
+ // watchingNamespaces and watchingLabels are empty means to monitor all namespaces.
+ if !validation.HasValueInSyncMap(c.watchingNamespaces) && len(c.watchingLabels) == 0 {
opts := v1.ListOptions{}
// list all namespaces
nsList, err := c.kubeClient.Client.CoreV1().Namespaces().List(ctx, opts)
@@ -64,6 +64,7 @@ func (c *Controller) CompareResources(ctx context.Context) error {
}
c.watchingNamespaces.Range(func(key, value interface{}) bool {
+ log.Debugf("start to watch namespace: %s", key)
wg.Add(1)
go func(ns string) {
defer wg.Done()
diff --git a/pkg/ingress/namespace.go b/pkg/ingress/namespace.go
index 0307151..1e4a566 100644
--- a/pkg/ingress/namespace.go
+++ b/pkg/ingress/namespace.go
@@ -68,7 +68,6 @@ func (c *Controller) initWatchingNamespacesByLabels(ctx context.Context) error {
c.watchingNamespaces.Store(ns.Name, struct{}{})
}
log.Infow("label selector watching namespaces", zap.Strings("namespaces", nss))
-
return nil
}
@@ -142,8 +141,9 @@ func (c *namespaceController) handleSyncErr(event *types.Event, err error) {
func (c *namespaceController) onAdd(obj interface{}) {
key, err := cache.MetaNamespaceKeyFunc(obj)
- if err == nil {
- log.Debugw(key)
+ if err != nil {
+ log.Errorf("found Namespace resource with error: %v", err)
+ return
}
c.workqueue.Add(&types.Event{
Type: types.EventAdd,
@@ -159,7 +159,7 @@ func (c *namespaceController) onUpdate(pre, cur interface{}) {
}
key, err := cache.MetaNamespaceKeyFunc(cur)
if err != nil {
- log.Errorf("found Namespace resource with error: %s", err)
+ log.Errorf("found Namespace resource with error: %v", err)
return
}
c.workqueue.Add(&types.Event{
diff --git a/test/e2e/ingress/namespace.go b/test/e2e/ingress/namespace.go
index ec249d0..649d49e 100644
--- a/test/e2e/ingress/namespace.go
+++ b/test/e2e/ingress/namespace.go
@@ -21,12 +21,21 @@ import (
"net/http"
"time"
+ "github.com/gruntwork-io/terratest/modules/k8s"
"github.com/onsi/ginkgo"
"github.com/stretchr/testify/assert"
"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
)
+type headers struct {
+ Headers struct {
+ Accept string `json:"Accept"`
+ Host string `json:"Host"`
+ UserAgent string `json:"User-Agent"`
+ } `json:"headers"`
+}
+
var _ = ginkgo.Describe("namespacing filtering", func() {
opts := &scaffold.Options{
Name: "default",
@@ -37,9 +46,10 @@ var _ = ginkgo.Describe("namespacing filtering", func() {
APISIXRouteVersion: "apisix.apache.org/v2beta3",
}
s := scaffold.NewScaffold(opts)
- ginkgo.It("resources in other namespaces should be ignored", func() {
- backendSvc, backendSvcPort := s.DefaultHTTPBackend()
- route := fmt.Sprintf(`
+ ginkgo.Context("with namespace_selector", func() {
+ ginkgo.It("resources in other namespaces should be ignored", func() {
+ backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+ route := fmt.Sprintf(`
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
@@ -57,18 +67,86 @@ spec:
servicePort: %d
`, backendSvc, backendSvcPort[0])
- assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(route), "creating ApisixRoute")
- time.Sleep(6 * time.Second)
- assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "checking number of routes")
- assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "checking number of upstreams")
+ assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(route), "creating ApisixRoute")
+ time.Sleep(6 * time.Second)
+ // assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "checking number of routes")
+ // assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "checking number of upstreams")
+
+ 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 ApisixRoute in default namespace.
+ route = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2beta3
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /headers
+ backends:
+ - serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+ assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromStringWithNamespace(route, "default"), "creating ApisixRoute")
+ _ = s.NewAPISIXClient().GET("/headers").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusNotFound)
+ })
+ })
+
+ 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.
+ ginkgo.BeforeEach(func() {
+ k8s.CreateNamespace(ginkgo.GinkgoT(), &k8s.KubectlOptions{
+ ConfigPath: scaffold.GetKubeconfig(),
+ }, namespace)
+ _, err := s.NewHTTPBINWithNamespace(namespace)
+ assert.Nil(ginkgo.GinkgoT(), err, "create second httpbin service")
+ })
- 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")
+ // clean this tmp namespace when test case is done.
+ ginkgo.AfterEach(func() {
+ err := k8s.DeleteNamespaceE(ginkgo.GinkgoT(), &k8s.KubectlOptions{
+ ConfigPath: scaffold.GetKubeconfig()}, namespace)
+ assert.Nilf(ginkgo.GinkgoT(), err, "deleting namespace %s", namespace)
+ })
- // Now create another ApisixRoute in default namespace.
- route = fmt.Sprintf(`
+ ginkgo.It("all resources will be watched", func() {
+ backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+ route := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2beta3
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /ip
+ backends:
+ - serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0])
+ assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(route), "creating first ApisixRoute")
+ time.Sleep(3 * time.Second)
+
+ // Now create another ApisixRoute in another namespace.
+ backendSvc, backendSvcPort = s.DefaultHTTPBackend()
+ route = fmt.Sprintf(`
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
@@ -86,7 +164,29 @@ spec:
servicePort: %d
`, backendSvc, backendSvcPort[0])
- assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromStringWithNamespace(route, "default"), "creating ApisixRoute")
- _ = s.NewAPISIXClient().GET("/headers").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusNotFound)
+ assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromStringWithNamespace(route, namespace), "creating second ApisixRoute")
+
+ // restart ingress-controller
+ pods, err := s.GetIngressPodDetails()
+ assert.Nil(ginkgo.GinkgoT(), err)
+ assert.Len(ginkgo.GinkgoT(), pods, 1)
+ ginkgo.GinkgoT().Logf("restart apisix-ingress-controller pod %s", pods[0].Name)
+ assert.Nil(ginkgo.GinkgoT(), s.KillPod(pods[0].Name))
+ time.Sleep(6 * time.Second)
+ // Two ApisixRoutes have been created at this time.
+ // assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "checking number of routes")
+ // assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "checking number of upstreams")
+
+ 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")
+ assert.NotEqual(ginkgo.GinkgoT(), ip{}, placeholder)
+ body = s.NewAPISIXClient().GET("/headers").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
+ var headerResponse headers
+ err = json.Unmarshal([]byte(body), &headerResponse)
+ assert.Nil(ginkgo.GinkgoT(), err, "unmarshalling header")
+ assert.NotEqual(ginkgo.GinkgoT(), headers{}, headerResponse)
+ })
})
})
diff --git a/test/e2e/ingress/sanity.go b/test/e2e/ingress/sanity.go
index 08247f7..05bef74 100644
--- a/test/e2e/ingress/sanity.go
+++ b/test/e2e/ingress/sanity.go
@@ -27,7 +27,7 @@ import (
)
type ip struct {
- IP string `json:"ip"`
+ IP string `json:"origin"`
}
var _ = ginkgo.Describe("single-route", func() {
@@ -71,6 +71,7 @@ spec:
var placeholder ip
err = json.Unmarshal([]byte(body), &placeholder)
assert.Nil(ginkgo.GinkgoT(), err, "unmarshalling IP")
+ assert.NotEqual(ginkgo.GinkgoT(), ip{}, placeholder)
// It's not our focus point to check the IP address returned by httpbin,
// so here skip the IP address validation.
})
@@ -124,6 +125,7 @@ spec:
var placeholder ip
err = json.Unmarshal([]byte(body), &placeholder)
assert.Nil(ginkgo.GinkgoT(), err, "unmarshalling IP")
+ assert.NotEqual(ginkgo.GinkgoT(), ip{}, placeholder)
body = s.NewAPISIXClient().GET("/json").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
var dummy map[string]interface{}
@@ -228,6 +230,7 @@ spec:
var placeholder ip
err = json.Unmarshal([]byte(body), &placeholder)
assert.Nil(ginkgo.GinkgoT(), err, "unmarshalling IP")
+ assert.NotEqual(ginkgo.GinkgoT(), ip{}, placeholder)
// It's not our focus point to check the IP address returned by httpbin,
// so here skip the IP address validation.
})
diff --git a/test/e2e/scaffold/httpbin.go b/test/e2e/scaffold/httpbin.go
index b2aaaa9..4d9a423 100644
--- a/test/e2e/scaffold/httpbin.go
+++ b/test/e2e/scaffold/httpbin.go
@@ -103,6 +103,15 @@ func (s *Scaffold) newHTTPBIN() (*corev1.Service, error) {
return svc, nil
}
+func (s *Scaffold) NewHTTPBINWithNamespace(namespace string) (*corev1.Service, error) {
+ originalNamespace := s.kubectlOptions.Namespace
+ s.kubectlOptions.Namespace = namespace
+ defer func() {
+ s.kubectlOptions.Namespace = originalNamespace
+ }()
+ return s.newHTTPBIN()
+}
+
// ScaleHTTPBIN scales the number of HTTPBIN pods to desired.
func (s *Scaffold) ScaleHTTPBIN(desired int) error {
httpbinDeployment := fmt.Sprintf(s.FormatRegistry(_httpbinDeploymentTemplate), desired)
diff --git a/test/e2e/scaffold/ingress.go b/test/e2e/scaffold/ingress.go
index d551eb4..a9e32f3 100644
--- a/test/e2e/scaffold/ingress.go
+++ b/test/e2e/scaffold/ingress.go
@@ -26,7 +26,6 @@ import (
"github.com/stretchr/testify/assert"
coordinationv1 "k8s.io/api/coordination/v1"
corev1 "k8s.io/api/core/v1"
- v1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -407,9 +406,11 @@ func (s *Scaffold) newIngressAPISIXController() error {
var ingressAPISIXDeployment string
label := fmt.Sprintf("apisix.ingress.watch=%s", s.namespace)
if s.opts.EnableWebhooks {
- ingressAPISIXDeployment = fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, _volumeMounts, _webhookCertSecret)
+ ingressAPISIXDeployment = fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), s.opts.IngressAPISIXReplicas, s.namespace,
+ s.FormatNamespaceLabel(label), s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, _volumeMounts, _webhookCertSecret)
} else {
- ingressAPISIXDeployment = fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, "", _webhookCertSecret)
+ ingressAPISIXDeployment = fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), s.opts.IngressAPISIXReplicas, s.namespace,
+ s.FormatNamespaceLabel(label), s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, "", _webhookCertSecret)
}
err = k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, ingressAPISIXDeployment)
@@ -504,7 +505,7 @@ func (s *Scaffold) WaitGetLeaderLease() (*coordinationv1.Lease, error) {
// GetIngressPodDetails returns a batch of pod description
// about apisix-ingress-controller.
-func (s *Scaffold) GetIngressPodDetails() ([]v1.Pod, error) {
+func (s *Scaffold) GetIngressPodDetails() ([]corev1.Pod, error) {
return k8s.ListPodsE(s.t, s.kubectlOptions, metav1.ListOptions{
LabelSelector: "app=ingress-apisix-controller-deployment-e2e-test",
})
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index 0963e9a..3aa2b67 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -38,22 +38,22 @@ import (
"github.com/gruntwork-io/terratest/modules/testing"
"github.com/onsi/ginkgo"
"github.com/stretchr/testify/assert"
- appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
)
type Options struct {
- Name string
- Kubeconfig string
- APISIXConfigPath string
- IngressAPISIXReplicas int
- HTTPBinServicePort int
- APISIXRouteVersion string
- APISIXAdminAPIKey string
- EnableWebhooks bool
- APISIXPublishAddress string
+ Name string
+ Kubeconfig string
+ APISIXConfigPath string
+ IngressAPISIXReplicas int
+ HTTPBinServicePort int
+ APISIXRouteVersion string
+ APISIXAdminAPIKey string
+ EnableWebhooks bool
+ APISIXPublishAddress string
+ disableNamespaceSelector bool
}
type Scaffold struct {
@@ -64,7 +64,6 @@ type Scaffold struct {
nodes []corev1.Node
etcdService *corev1.Service
apisixService *corev1.Service
- httpbinDeployment *appsv1.Deployment
httpbinService *corev1.Service
testBackendService *corev1.Service
finializers []func()
@@ -471,6 +470,18 @@ 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
+}
+
+func (s *Scaffold) DisableNamespaceSelector() {
+ s.opts.disableNamespaceSelector = true
+}
+
func waitExponentialBackoff(condFunc func() (bool, error)) error {
backoff := wait.Backoff{
Duration: 500 * time.Millisecond,