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 2023/03/17 06:41:14 UTC

[apisix-ingress-controller] branch master updated: feat: ApisixClusterConfig support IngressClass (#1720)

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 271d89fe feat: ApisixClusterConfig support IngressClass (#1720)
271d89fe is described below

commit 271d89feedc73619ccf8c2780bb124aba9b019d7
Author: Xin Rong <al...@gmail.com>
AuthorDate: Fri Mar 17 14:41:06 2023 +0800

    feat: ApisixClusterConfig support IngressClass (#1720)
---
 pkg/kube/apisix/apis/config/v2/types.go            |   6 +
 pkg/providers/apisix/apisix_cluster_config.go      |  33 ++++-
 samples/deploy/crd/v1/ApisixClusterConfig.yaml     |   2 +
 .../suite-ingress-features/ingress-class.go        | 149 +++++++++++++++++++++
 4 files changed, 186 insertions(+), 4 deletions(-)

diff --git a/pkg/kube/apisix/apis/config/v2/types.go b/pkg/kube/apisix/apis/config/v2/types.go
index 71951c7a..0b2c0626 100644
--- a/pkg/kube/apisix/apis/config/v2/types.go
+++ b/pkg/kube/apisix/apis/config/v2/types.go
@@ -291,6 +291,12 @@ type ApisixClusterConfig struct {
 
 // ApisixClusterConfigSpec defines the desired state of ApisixClusterConfigSpec.
 type ApisixClusterConfigSpec struct {
+	// IngressClassName is the name of an IngressClass cluster resource.
+	// controller implementations use this field to know whether they should be
+	// serving this ApisixClusterConfig resource, by a transitive connection
+	// (controller -> IngressClass -> ApisixClusterConfig resource).
+	// +optional
+	IngressClassName string `json:"ingressClassName,omitempty" yaml:"ingressClassName,omitempty"`
 	// Monitoring categories all monitoring related features.
 	// +optional
 	Monitoring *ApisixClusterMonitoringConfig `json:"monitoring" yaml:"monitoring"`
diff --git a/pkg/providers/apisix/apisix_cluster_config.go b/pkg/providers/apisix/apisix_cluster_config.go
index d5348fac..21609e01 100644
--- a/pkg/providers/apisix/apisix_cluster_config.go
+++ b/pkg/providers/apisix/apisix_cluster_config.go
@@ -320,6 +320,9 @@ func (c *apisixClusterConfigController) onAdd(obj interface{}) {
 		log.Errorf("found ApisixClusterConfig resource with bad meta key: %s", err.Error())
 		return
 	}
+	if !c.isEffective(acc) {
+		return
+	}
 	log.Debugw("ApisixClusterConfig add event arrived",
 		zap.String("key", key),
 		zap.Any("object", obj),
@@ -355,6 +358,9 @@ func (c *apisixClusterConfigController) onUpdate(oldObj, newObj interface{}) {
 		log.Errorf("found ApisixClusterConfig with bad meta key: %s", err)
 		return
 	}
+	if !c.isEffective(curr) {
+		return
+	}
 	log.Debugw("ApisixClusterConfig update event arrived",
 		zap.Any("new object", curr),
 		zap.Any("old object", prev),
@@ -391,6 +397,9 @@ func (c *apisixClusterConfigController) onDelete(obj interface{}) {
 		log.Errorf("found ApisixClusterConfig resource with bad meta key: %s", err)
 		return
 	}
+	if !c.isEffective(acc) {
+		return
+	}
 	log.Debugw("ApisixClusterConfig delete event arrived",
 		zap.Any("final state", acc),
 	)
@@ -414,13 +423,13 @@ func (c *apisixClusterConfigController) ResourceSync() {
 			log.Errorw("ApisixClusterConfig sync failed, found ApisixClusterConfig resource with bad meta namespace key", zap.String("error", err.Error()))
 			continue
 		}
-		if !c.namespaceProvider.IsWatchingNamespace(key) {
-			continue
-		}
 		acc, err := kube.NewApisixClusterConfig(obj)
 		if err != nil {
 			log.Errorw("found ApisixClusterConfig resource with bad type", zap.String("error", err.Error()))
-			return
+			continue
+		}
+		if !c.isEffective(acc) {
+			continue
 		}
 		c.workqueue.Add(&types.Event{
 			Type: types.EventAdd,
@@ -493,3 +502,19 @@ func (c *apisixClusterConfigController) recordStatus(at interface{}, reason stri
 		log.Errorf("unsupported resource record: %s", v)
 	}
 }
+
+func (c *apisixClusterConfigController) isEffective(agr kube.ApisixClusterConfig) bool {
+	if agr.GroupVersion() == config.ApisixV2 {
+		ingClassName := agr.V2().Spec.IngressClassName
+		ok := utils.MatchCRDsIngressClass(ingClassName, c.Kubernetes.IngressClass)
+		if !ok {
+			log.Debugw("IngressClass: ApisixClusterConfig ignored",
+				zap.String("key", agr.V2().Name),
+				zap.String("ingressClass", agr.V2().Spec.IngressClassName),
+			)
+		}
+		return ok
+	}
+	// Compatible with legacy versions
+	return true
+}
diff --git a/samples/deploy/crd/v1/ApisixClusterConfig.yaml b/samples/deploy/crd/v1/ApisixClusterConfig.yaml
index e289da07..efddfff6 100644
--- a/samples/deploy/crd/v1/ApisixClusterConfig.yaml
+++ b/samples/deploy/crd/v1/ApisixClusterConfig.yaml
@@ -81,6 +81,8 @@ spec:
             spec:
               type: object
               properties:
+                ingressClassName:
+                  type: string
                 admin:
                   type: object
                   required:
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 dc5c0672..ea4222ca 100644
--- a/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
+++ b/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
@@ -19,6 +19,7 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/apache/apisix-ingress-controller/pkg/id"
 	ginkgo "github.com/onsi/ginkgo/v2"
 	"github.com/stretchr/testify/assert"
 
@@ -472,6 +473,81 @@ spec:
 		assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "james")
 		assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "james-key"}, acs[0].Plugins["key-auth"])
 	})
+
+	ginkgo.It("ApisiClusterConfig should be ignored", func() {
+		// create ApisixConsumer resource with ingressClassName: ignore
+		acc := `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  ingressClassName: ignore
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err := s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok := agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+	})
+
+	ginkgo.It("ApisiClusterConfig should be handled", func() {
+		// create ApisixConsumer resource without ingressClassName
+		acc := `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err := s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok := agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+
+		// update ApisixConsumer resource with ingressClassName: apisix
+		acc = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  ingressClassName: apisix
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err = s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok = agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+	})
 })
 
 var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs with IngressClass apisix-and-all", func() {
@@ -770,4 +846,77 @@ spec:
 		assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "james")
 		assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "james-password"}, acs[0].Plugins["key-auth"])
 	})
+
+	ginkgo.It("ApisiClusterConfig should be handled", func() {
+		// create ApisixConsumer resource without ingressClassName
+		acc := `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err := s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok := agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+
+		// update ApisixConsumer resource with ingressClassName: apisix
+		acc = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  ingressClassName: apisix
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err = s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok = agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+
+		// update ApisixConsumer resource with ingressClassName: watch
+		acc = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixClusterConfig
+metadata:
+  name: default
+spec:
+  ingressClassName: watch
+  monitoring:
+    prometheus:
+      enable: true
+      prefer_name: true
+`
+		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(acc))
+		time.Sleep(6 * time.Second)
+
+		agrs, err = s.ListApisixGlobalRules()
+		assert.Nil(ginkgo.GinkgoT(), err)
+		assert.Len(ginkgo.GinkgoT(), agrs, 1)
+		assert.Equal(ginkgo.GinkgoT(), agrs[0].ID, id.GenID("default"))
+		assert.Len(ginkgo.GinkgoT(), agrs[0].Plugins, 1)
+		_, ok = agrs[0].Plugins["prometheus"]
+		assert.Equal(ginkgo.GinkgoT(), ok, true)
+	})
 })