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 93c795b3 feat: support ingressClass for ApisixPluginConfig (#1716)
93c795b3 is described below

commit 93c795b327fc4e9185e26a8eacc8de01774dd6e4
Author: Sarasa Kisaragi <[email protected]>
AuthorDate: Fri Mar 10 18:09:14 2023 +0800

    feat: support ingressClass for ApisixPluginConfig (#1716)
    
    Signed-off-by: Ling Samuel <[email protected]>
---
 pkg/kube/apisix/apis/config/v2/types.go            |   4 +
 pkg/providers/apisix/apisix_plugin_config.go       |  33 ++-
 samples/deploy/crd/v1/ApisixPluginConfig.yaml      |   2 +
 .../suite-ingress-features/ingress-class.go        | 256 ++++++++++++++++++++-
 4 files changed, 290 insertions(+), 5 deletions(-)

diff --git a/pkg/kube/apisix/apis/config/v2/types.go 
b/pkg/kube/apisix/apis/config/v2/types.go
index ae518a5e..fbbfb5ce 100644
--- a/pkg/kube/apisix/apis/config/v2/types.go
+++ b/pkg/kube/apisix/apis/config/v2/types.go
@@ -774,6 +774,10 @@ type ApisixPluginConfig struct {
 
 // ApisixPluginConfigSpec defines the desired state of ApisixPluginConfigSpec.
 type ApisixPluginConfigSpec struct {
+       // IngressClassName is the name of an IngressClass cluster resource.
+       // The controller uses this field to decide whether the resource should 
be managed or not.
+       // +optional
+       IngressClassName string `json:"ingressClassName,omitempty" 
yaml:"ingressClassName,omitempty"`
        // Plugins contains a list of ApisixRoutePlugin
        // +required
        Plugins []ApisixRoutePlugin `json:"plugins" yaml:"plugins"`
diff --git a/pkg/providers/apisix/apisix_plugin_config.go 
b/pkg/providers/apisix/apisix_plugin_config.go
index 1f60e59a..575af95b 100644
--- a/pkg/providers/apisix/apisix_plugin_config.go
+++ b/pkg/providers/apisix/apisix_plugin_config.go
@@ -288,13 +288,16 @@ func (c *apisixPluginConfigController) onAdd(obj 
interface{}) {
                log.Errorf("found ApisixPluginConfig resource with bad meta 
namespace key: %s", err)
                return
        }
+       apc := kube.MustNewApisixPluginConfig(obj)
+       if !c.isEffective(apc) {
+               return
+       }
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
        log.Debugw("ApisixPluginConfig add event arrived",
                zap.Any("object", obj))
 
-       apc := kube.MustNewApisixPluginConfig(obj)
        c.workqueue.Add(&types.Event{
                Type: types.EventAdd,
                Object: kube.ApisixPluginConfigEvent{
@@ -317,6 +320,9 @@ func (c *apisixPluginConfigController) onUpdate(oldObj, 
newObj interface{}) {
                log.Errorf("found ApisixPluginConfig resource with bad meta 
namespace key: %s", err)
                return
        }
+       if !c.isEffective(curr) {
+               return
+       }
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
@@ -350,6 +356,9 @@ func (c *apisixPluginConfigController) onDelete(obj 
interface{}) {
                log.Errorf("found ApisixPluginConfig resource with bad meta 
namesapce key: %s", err)
                return
        }
+       if !c.isEffective(apc) {
+               return
+       }
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
@@ -376,10 +385,13 @@ func (c *apisixPluginConfigController) ResourceSync() {
                        log.Errorw("ApisixPluginConfig sync failed, found 
ApisixPluginConfig resource with bad meta namespace key", zap.String("error", 
err.Error()))
                        continue
                }
+               apc := kube.MustNewApisixPluginConfig(obj)
+               if !c.isEffective(apc) {
+                       continue
+               }
                if !c.namespaceProvider.IsWatchingNamespace(key) {
                        continue
                }
-               apc := kube.MustNewApisixPluginConfig(obj)
                c.workqueue.Add(&types.Event{
                        Type: types.EventAdd,
                        Object: kube.ApisixPluginConfigEvent{
@@ -453,3 +465,20 @@ func (c *apisixPluginConfigController) recordStatus(at 
interface{}, reason strin
                log.Errorf("unsupported resource record: %s", v)
        }
 }
+
+func (c *apisixPluginConfigController) isEffective(apc 
kube.ApisixPluginConfig) bool {
+       if apc.GroupVersion() == config.ApisixV2 {
+               ingClassName := apc.V2().Spec.IngressClassName
+               ok := utils.MatchCRDsIngressClass(ingClassName, 
c.Kubernetes.IngressClass)
+               if !ok {
+                       log.Debugw("IngressClass: ApisixPluginConfig ignored",
+                               zap.String("key", 
apc.V2().Namespace+"/"+apc.V2().Name),
+                               zap.String("ingressClass", 
apc.V2().Spec.IngressClassName),
+                       )
+               }
+
+               return ok
+       }
+       // Compatible with legacy versions
+       return true
+}
diff --git a/samples/deploy/crd/v1/ApisixPluginConfig.yaml 
b/samples/deploy/crd/v1/ApisixPluginConfig.yaml
index c49b27bf..0c765c68 100644
--- a/samples/deploy/crd/v1/ApisixPluginConfig.yaml
+++ b/samples/deploy/crd/v1/ApisixPluginConfig.yaml
@@ -101,6 +101,8 @@ spec:
               required:
                 - plugins
               properties:
+                ingressClassName:
+                  type: string
                 plugins:
                   type: array
                   items:
diff --git a/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go 
b/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
index ef2face6..a61a0a41 100644
--- a/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
+++ b/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
@@ -31,7 +31,7 @@ var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs 
with IngressClass"
                IngressAPISIXReplicas: 1,
                IngressClass:          "apisix",
        })
-       ginkgo.It("ApisiUpstream should be ignored", func() {
+       ginkgo.It("ApisixUpstream should be ignored", func() {
                backendSvc, backendSvcPort := s.DefaultHTTPBackend()
                au := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2
@@ -78,7 +78,7 @@ spec:
                s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
        })
 
-       ginkgo.It("ApisiUpstream should be handled", func() {
+       ginkgo.It("ApisixUpstream should be handled", func() {
                backendSvc, backendSvcPort := s.DefaultHTTPBackend()
                au := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2
@@ -135,6 +135,155 @@ spec:
 
                s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
        })
+
+       ginkgo.It("ApisixPluginConfig should be ignored", func() {
+               backendSvc, backendPorts := s.DefaultHTTPBackend()
+               apc := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixPluginConfig
+metadata:
+  name: test-apc-1
+spec:
+  ingressClassName: ignored
+  plugins:
+  - name: echo
+    enable: true
+    config:
+      body: "my custom body"
+`)
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(apc))
+
+               ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+   match:
+     hosts:
+     - httpbin.org
+     paths:
+       - /ip
+   backends:
+   - serviceName: %s
+     servicePort: %d
+     weight: 10
+   plugin_config_name: test-apc-1
+`, backendSvc, backendPorts[0])
+
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(ar))
+
+               // The referenced plugin doesn't exist so the translation 
expected to be failed
+               err := s.EnsureNumApisixUpstreamsCreated(0)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               err = s.EnsureNumApisixPluginConfigCreated(0)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
pluginConfigs")
+               err = s.EnsureNumApisixRoutesCreated(0)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+       })
+
+       ginkgo.It("ApisixPluginConfig should be handled", func() {
+               backendSvc, backendPorts := s.DefaultHTTPBackend()
+               apc := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixPluginConfig
+metadata:
+  name: test-apc-1
+spec:
+  ingressClassName: apisix
+  plugins:
+  - name: echo
+    enable: true
+    config:
+      body: "my custom body"
+`)
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(apc))
+
+               ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+   match:
+     hosts:
+     - httpbin.org
+     paths:
+       - /ip
+   backends:
+   - serviceName: %s
+     servicePort: %d
+     weight: 10
+   plugin_config_name: test-apc-1
+`, backendSvc, backendPorts[0])
+
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(ar))
+
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               err = s.EnsureNumApisixPluginConfigCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
pluginConfigs")
+               err = s.EnsureNumApisixRoutesCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+               resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect()
+               resp.Status(http.StatusOK)
+               resp.Body().IsEqual("my custom body")
+       })
+
+       ginkgo.It("ApisixPluginConfig should be handled without ingressClass", 
func() {
+               backendSvc, backendPorts := s.DefaultHTTPBackend()
+               apc := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixPluginConfig
+metadata:
+  name: test-apc-1
+spec:
+  plugins:
+  - name: echo
+    enable: true
+    config:
+      body: "my custom body"
+`)
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(apc))
+
+               ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+   match:
+     hosts:
+     - httpbin.org
+     paths:
+       - /ip
+   backends:
+   - serviceName: %s
+     servicePort: %d
+     weight: 10
+   plugin_config_name: test-apc-1
+`, backendSvc, backendPorts[0])
+
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(ar))
+
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               err = s.EnsureNumApisixPluginConfigCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
pluginConfigs")
+               err = s.EnsureNumApisixRoutesCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+               resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect()
+               resp.Status(http.StatusOK)
+               resp.Body().IsEqual("my custom body")
+       })
 })
 
 var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs with 
IngressClass apisix-and-all", func() {
@@ -144,7 +293,7 @@ var _ = ginkgo.Describe("suite-ingress-features: Testing 
CRDs with IngressClass
                IngressClass:          "apisix-and-all",
        })
 
-       ginkgo.It("ApisiUpstream should be handled", func() {
+       ginkgo.It("ApisixUpstream should be handled", func() {
                backendSvc, backendSvcPort := s.DefaultHTTPBackend()
                au := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2
@@ -220,4 +369,105 @@ spec:
 
                s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
        })
+
+       ginkgo.It("ApisixPluginConfig should be handled", func() {
+               backendSvc, backendPorts := s.DefaultHTTPBackend()
+               apc := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixPluginConfig
+metadata:
+  name: test-apc-1
+spec:
+  ingressClassName: apisix
+  plugins:
+  - name: echo
+    enable: true
+    config:
+      body: "my custom body"
+`)
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(apc))
+
+               ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+   match:
+     hosts:
+     - httpbin.org
+     paths:
+       - /ip
+   backends:
+   - serviceName: %s
+     servicePort: %d
+     weight: 10
+   plugin_config_name: test-apc-1
+`, backendSvc, backendPorts[0])
+
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(ar))
+
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               err = s.EnsureNumApisixPluginConfigCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
pluginConfigs")
+               err = s.EnsureNumApisixRoutesCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+               resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect()
+               resp.Status(http.StatusOK)
+               resp.Body().IsEqual("my custom body")
+       })
+
+       ginkgo.It("ApisixPluginConfig should be handled without ingressClass", 
func() {
+               backendSvc, backendPorts := s.DefaultHTTPBackend()
+               apc := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixPluginConfig
+metadata:
+  name: test-apc-1
+spec:
+  plugins:
+  - name: echo
+    enable: true
+    config:
+      body: "my custom body"
+`)
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(apc))
+
+               ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+   match:
+     hosts:
+     - httpbin.org
+     paths:
+       - /ip
+   backends:
+   - serviceName: %s
+     servicePort: %d
+     weight: 10
+   plugin_config_name: test-apc-1
+`, backendSvc, backendPorts[0])
+
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateVersionedApisixResource(ar))
+
+               err := s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+               err = s.EnsureNumApisixPluginConfigCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
pluginConfigs")
+               err = s.EnsureNumApisixRoutesCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+               resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect()
+               resp.Status(http.StatusOK)
+               resp.Body().IsEqual("my custom body")
+       })
 })

Reply via email to