You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by kv...@apache.org on 2022/06/01 10:43:51 UTC

[apisix-ingress-controller] branch master updated: e2e-test: add e2e tests and CRDs for ApisixConsumer v2 (#1044)

This is an automated email from the ASF dual-hosted git repository.

kvn 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 e1d496dd e2e-test: add e2e tests and CRDs for ApisixConsumer v2 (#1044)
e1d496dd is described below

commit e1d496dd074eb19982b9e198370440ebd0d16f87
Author: Sarasa Kisaragi <li...@gmail.com>
AuthorDate: Wed Jun 1 18:43:46 2022 +0800

    e2e-test: add e2e tests and CRDs for ApisixConsumer v2 (#1044)
---
 samples/deploy/crd/v1/ApisixConsumer.yaml   |  168 ++++
 test/e2e/scaffold/consumer.go               |   55 +-
 test/e2e/scaffold/scaffold.go               |   15 +
 test/e2e/suite-annotations/authorization.go |  339 ++++----
 test/e2e/suite-features/consumer.go         | 1126 +++++++++++++--------------
 5 files changed, 951 insertions(+), 752 deletions(-)

diff --git a/samples/deploy/crd/v1/ApisixConsumer.yaml b/samples/deploy/crd/v1/ApisixConsumer.yaml
index 32498386..90346304 100644
--- a/samples/deploy/crd/v1/ApisixConsumer.yaml
+++ b/samples/deploy/crd/v1/ApisixConsumer.yaml
@@ -31,6 +31,174 @@ spec:
   preserveUnknownFields: false
   versions:
     - name: v2beta3
+      served: true
+      storage: false
+      subresources:
+        status: {}
+      schema:
+        openAPIV3Schema:
+          type: object
+          properties:
+            spec:
+              type: object
+              required:
+                - authParameter
+              properties:
+                authParameter:
+                  type: object
+                  oneOf:
+                    - required: ["basicAuth"]
+                    - required: ["keyAuth"]
+                    - required: ["wolfRBAC"]
+                    - required: ["jwtAuth"]
+                    - required: ["hmacAuth"]
+                  properties:
+                    basicAuth:
+                      type: object
+                      oneOf:
+                        - required: ["value"]
+                        - required: ["secretRef"]
+                      properties:
+                        value:
+                          type: object
+                          properties:
+                            username:
+                              type: string
+                              minLength: 1
+                            password:
+                              type: string
+                              minLength: 1
+                          required:
+                            - username
+                            - password
+                        secretRef:
+                          type: object
+                          properties:
+                            name:
+                              type: string
+                              minLength: 1
+                          required:
+                            - name
+                    keyAuth:
+                      type: object
+                      oneOf:
+                        - required: ["value"]
+                        - required: ["secretRef"]
+                      properties:
+                        value:
+                          type: object
+                          properties:
+                            key:
+                              type: string
+                              minLength: 1
+                          required:
+                            - key
+                        secretRef:
+                          type: object
+                          properties:
+                            name:
+                              type: string
+                              minLength: 1
+                          required:
+                            - name
+                    jwtAuth:
+                      type: object
+                      oneOf:
+                        - required: ["value"]
+                        - required: ["secretRef"]
+                      properties:
+                        value:
+                          type: object
+                          properties:
+                            key:
+                              type: string
+                              minLength: 1
+                            secret:
+                              type: string
+                            public_key:
+                              type: string
+                            private_key:
+                              type: string
+                            algorithm:
+                              type: string
+                            exp:
+                              type: integer
+                            base64_secret:
+                              type: boolean
+                          required:
+                            - key
+                        secretRef:
+                          type: object
+                          properties:
+                            name:
+                              type: string
+                              minLength: 1
+                          required:
+                            - name
+                    wolfRBAC:
+                      type: object
+                      oneOf:
+                        - required: ["value"]
+                        - required: ["secretRef"]
+                      properties:
+                        value:
+                          type: object
+                          properties:
+                            server:
+                              type: string
+                            appid:
+                              type: string
+                            header_prefix:
+                              type: string
+                        secretRef:
+                          type: object
+                          properties:
+                            name:
+                              type: string
+                              minLength: 1
+                          required:
+                            - name
+                    hmacAuth:
+                      type: object
+                      oneOf:
+                        - required: ["value"]
+                        - required: ["secretRef"]
+                      properties:
+                        value:
+                          type: object
+                          properties:
+                            access_key:
+                              type: string
+                            secret_key:
+                              type: string
+                            algorithm:
+                              type: string
+                            clock_skew:
+                              type: integer
+                            signed_headers:
+                              type: array
+                              items:
+                                type: string
+                            keep_headers:
+                              type: boolean
+                            encode_uri_params:
+                              type: boolean
+                            validate_request_body:
+                              type: boolean
+                            max_req_body:
+                              type: integer
+                          required:
+                            - access_key
+                            - secret_key
+                        secretRef:
+                          type: object
+                          properties:
+                            name:
+                              type: string
+                              minLength: 1
+                          required:
+                            - name
+    - name: v2
       served: true
       storage: true
       subresources:
diff --git a/test/e2e/scaffold/consumer.go b/test/e2e/scaffold/consumer.go
index 5cee9b24..5aac1455 100644
--- a/test/e2e/scaffold/consumer.go
+++ b/test/e2e/scaffold/consumer.go
@@ -14,11 +14,15 @@
 // limitations under the License.
 package scaffold
 
-import "fmt"
+import (
+	"errors"
+	"fmt"
+	"strings"
+)
 
 var (
 	_apisixConsumerBasicAuth = `
-apiVersion: apisix.apache.org/v2beta3
+apiVersion: %s
 kind: ApisixConsumer
 metadata:
   name: %s
@@ -28,9 +32,20 @@ spec:
       value:
         username: %s
         password: %s
+`
+	_apisixConsumerBasicAuthSecret = `
+apiVersion: %s
+kind: ApisixConsumer
+metadata:
+  name: %s
+spec:
+  authParameter:
+    basicAuth:
+      secretRef:
+        name: %s
 `
 	_apisixConsumerKeyAuth = `
-  apiVersion: apisix.apache.org/v2beta3
+  apiVersion: %s
   kind: ApisixConsumer
   metadata:
     name: %s
@@ -39,15 +54,45 @@ spec:
       keyAuth:
         value:
           key: %s
+  `
+	_apisixConsumerKeyAuthSecret = `
+  apiVersion: %s
+  kind: ApisixConsumer
+  metadata:
+    name: %s
+  spec:
+    authParameter:
+      keyAuth:
+        secretRef:
+          name: %s
   `
 )
 
 func (s *Scaffold) ApisixConsumerBasicAuthCreated(name, username, password string) error {
-	ac := fmt.Sprintf(_apisixConsumerBasicAuth, name, username, password)
+	ac := fmt.Sprintf(_apisixConsumerBasicAuth, s.opts.APISIXConsumerVersion, name, username, password)
+	return s.CreateResourceFromString(ac)
+}
+
+func (s *Scaffold) ApisixConsumerBasicAuthSecretCreated(name, secret string) error {
+	ac := fmt.Sprintf(_apisixConsumerBasicAuthSecret, s.opts.APISIXConsumerVersion, name, secret)
 	return s.CreateResourceFromString(ac)
 }
 
 func (s *Scaffold) ApisixConsumerKeyAuthCreated(name, key string) error {
-	ac := fmt.Sprintf(_apisixConsumerKeyAuth, name, key)
+	ac := fmt.Sprintf(_apisixConsumerKeyAuth, s.opts.APISIXConsumerVersion, name, key)
+	return s.CreateResourceFromString(ac)
+}
+
+func (s *Scaffold) ApisixConsumerKeyAuthSecretCreated(name, secret string) error {
+	ac := fmt.Sprintf(_apisixConsumerKeyAuthSecret, s.opts.APISIXConsumerVersion, name, secret)
+	return s.CreateResourceFromString(ac)
+}
+
+func (s *Scaffold) CreateVersionedApisixConsumer(yml string) error {
+	if !strings.Contains(yml, "kind: ApisixConsumer") {
+		return errors.New("not a ApisixConsumer")
+	}
+
+	ac := s.replaceApiVersion(yml, s.opts.APISIXConsumerVersion)
 	return s.CreateResourceFromString(ac)
 }
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index 9a47eb00..32c27387 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -28,6 +28,7 @@ import (
 	"os/exec"
 	"os/user"
 	"path/filepath"
+	"regexp"
 	"strings"
 	"text/template"
 	"time"
@@ -52,6 +53,7 @@ type Options struct {
 	HTTPBinServicePort         int
 	APISIXRouteVersion         string
 	APISIXTlsVersion           string
+	APISIXConsumerVersion      string
 	APISIXClusterConfigVersion string
 	APISIXAdminAPIKey          string
 	EnableWebhooks             bool
@@ -110,6 +112,9 @@ func NewScaffold(o *Options) *Scaffold {
 	if o.APISIXTlsVersion == "" {
 		o.APISIXTlsVersion = config.ApisixV2beta3
 	}
+	if o.APISIXConsumerVersion == "" {
+		o.APISIXConsumerVersion = config.ApisixV2beta3
+	}
 	if o.APISIXClusterConfigVersion == "" {
 		o.APISIXClusterConfigVersion = config.ApisixV2beta3
 	}
@@ -139,6 +144,7 @@ func NewDefaultScaffold() *Scaffold {
 		HTTPBinServicePort:         80,
 		APISIXRouteVersion:         kube.ApisixRouteV2beta3,
 		APISIXTlsVersion:           config.ApisixV2beta3,
+		APISIXConsumerVersion:      config.ApisixV2beta3,
 		APISIXClusterConfigVersion: config.ApisixV2beta3,
 		EnableWebhooks:             false,
 		APISIXPublishAddress:       "",
@@ -156,6 +162,7 @@ func NewDefaultV2Scaffold() *Scaffold {
 		HTTPBinServicePort:         80,
 		APISIXRouteVersion:         kube.ApisixRouteV2,
 		APISIXTlsVersion:           config.ApisixV2,
+		APISIXConsumerVersion:      config.ApisixV2,
 		APISIXClusterConfigVersion: config.ApisixV2,
 		EnableWebhooks:             false,
 		APISIXPublishAddress:       "",
@@ -491,6 +498,14 @@ func (s *Scaffold) FormatNamespaceLabel(label string) string {
 	return label
 }
 
+var (
+	versionRegex = regexp.MustCompile(`apiVersion: apisix.apache.org/.*?\n`)
+)
+
+func (s *Scaffold) replaceApiVersion(yml, ver string) string {
+	return versionRegex.ReplaceAllString(yml, "apiVersion: "+ver+"\n")
+}
+
 func (s *Scaffold) DisableNamespaceSelector() {
 	s.opts.disableNamespaceSelector = true
 }
diff --git a/test/e2e/suite-annotations/authorization.go b/test/e2e/suite-annotations/authorization.go
index d1818651..13fad3e5 100644
--- a/test/e2e/suite-annotations/authorization.go
+++ b/test/e2e/suite-annotations/authorization.go
@@ -26,17 +26,18 @@ import (
 )
 
 var _ = ginkgo.Describe("suite-annotations: authorization annotations", func() {
-	s := scaffold.NewDefaultScaffold()
+	suites := func(scaffoldFunc func() *scaffold.Scaffold) {
+		s := scaffoldFunc()
 
-	ginkgo.It("enable keyAuth in ingress networking/v1", func() {
-		err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+		ginkgo.It("enable keyAuth in ingress networking/v1", func() {
+			err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
 
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
 
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
@@ -57,34 +58,34 @@ spec:
             port:
               number: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("apikey", "bar").
-			Expect().
-			Status(http.StatusOK)
-	})
-
-	ginkgo.It("enable keyAuth in ingress networking/v1beta1", func() {
-		err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("apikey", "bar").
+				Expect().
+				Status(http.StatusOK)
+		})
+
+		ginkgo.It("enable keyAuth in ingress networking/v1beta1", func() {
+			err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: networking.k8s.io/v1beta1
 kind: Ingress
 metadata:
@@ -103,34 +104,34 @@ spec:
           serviceName: %s
           servicePort: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("apikey", "bar").
-			Expect().
-			Status(http.StatusOK)
-	})
-
-	ginkgo.It("enable keyAuth in ingress extensions/v1beta1", func() {
-		err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("apikey", "bar").
+				Expect().
+				Status(http.StatusOK)
+		})
+
+		ginkgo.It("enable keyAuth in ingress extensions/v1beta1", func() {
+			err := s.ApisixConsumerKeyAuthCreated("foo", "bar")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
@@ -149,34 +150,34 @@ spec:
           serviceName: %s
           servicePort: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("apikey", "bar").
-			Expect().
-			Status(http.StatusOK)
-	})
-
-	ginkgo.It("enable basicAuth in ingress networking/v1", func() {
-		err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing API key found in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("apikey", "bar").
+				Expect().
+				Status(http.StatusOK)
+		})
+
+		ginkgo.It("enable basicAuth in ingress networking/v1", func() {
+			err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
@@ -197,34 +198,34 @@ spec:
             port:
               number: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
-			Expect().
-			Status(http.StatusOK)
-	})
-
-	ginkgo.It("enable basicAuth in ingress networking/v1beta1", func() {
-		err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
+				Expect().
+				Status(http.StatusOK)
+		})
+
+		ginkgo.It("enable basicAuth in ingress networking/v1beta1", func() {
+			err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: networking.k8s.io/v1beta1
 kind: Ingress
 metadata:
@@ -243,34 +244,34 @@ spec:
           serviceName: %s
           servicePort: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
-			Expect().
-			Status(http.StatusOK)
-	})
-
-	ginkgo.It("enable basicAuth in ingress networking/v1beta1", func() {
-		err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
-		assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		backendSvc, backendPort := s.DefaultHTTPBackend()
-		ing := fmt.Sprintf(`
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
+				Expect().
+				Status(http.StatusOK)
+		})
+
+		ginkgo.It("enable basicAuth in ingress networking/v1beta1", func() {
+			err := s.ApisixConsumerBasicAuthCreated("jack1", "jack1-username", "jack1-password")
+			assert.Nil(ginkgo.GinkgoT(), err, "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			backendSvc, backendPort := s.DefaultHTTPBackend()
+			ing := fmt.Sprintf(`
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
@@ -289,22 +290,30 @@ spec:
           serviceName: %s
           servicePort: %d
 `, backendSvc, backendPort[0])
-		err = s.CreateResourceFromString(ing)
-		assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
-		time.Sleep(5 * time.Second)
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
-			Expect().
-			Status(http.StatusOK)
+			err = s.CreateResourceFromString(ing)
+			assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
+			time.Sleep(5 * time.Second)
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing authorization in request")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", "Basic amFjazEtdXNlcm5hbWU6amFjazEtcGFzc3dvcmQ=").
+				Expect().
+				Status(http.StatusOK)
+		})
+	}
+
+	ginkgo.Describe("suite-annotations: scaffold v2beta3", func() {
+		suites(scaffold.NewDefaultScaffold)
+	})
+	ginkgo.Describe("suite-annotations: scaffold v2", func() {
+		suites(scaffold.NewDefaultV2Scaffold)
 	})
 })
diff --git a/test/e2e/suite-features/consumer.go b/test/e2e/suite-features/consumer.go
index 599e0063..d6fd80b0 100644
--- a/test/e2e/suite-features/consumer.go
+++ b/test/e2e/suite-features/consumer.go
@@ -28,38 +28,27 @@ import (
 )
 
 var _ = ginkgo.Describe("suite-features: ApisixConsumer", func() {
-	s := scaffold.NewDefaultScaffold()
-
-	ginkgo.It("ApisixRoute with basicAuth consumer", func() {
-		ac := `
-apiVersion: apisix.apache.org/v2beta3
-kind: ApisixConsumer
-metadata:
-  name: basicvalue
-spec:
-  authParameter:
-    basicAuth:
-      value:
-        username: foo
-        password: bar
-`
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating basicAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		basicAuth, _ := grs[0].Plugins["basic-auth"]
-		assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
-			"username": "foo",
-			"password": "bar",
-		})
-
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+	suites := func(scaffoldFunc func() *scaffold.Scaffold) {
+		s := scaffoldFunc()
+
+		ginkgo.It("ApisixRoute with basicAuth consumer", func() {
+			assert.Nil(ginkgo.GinkgoT(), s.ApisixConsumerBasicAuthCreated("basicvalue", "foo", "bar"), "creating basicAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			basicAuth, _ := grs[0].Plugins["basic-auth"]
+			assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
+				"username": "foo",
+				"password": "bar",
+			})
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -85,39 +74,39 @@ spec:
      enable: true
      type: basicAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with basicAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("Authorization", "Basic Zm9vOmJhcg==").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "Missing authorization in request")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("Authorization", "Basic Zm9vOmJhcg==").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with basicAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("Authorization", "Basic Zm9vOmJhcg==").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "Missing authorization in request")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("Authorization", "Basic Zm9vOmJhcg==").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
+		})
 
-	ginkgo.It("ApisixRoute with basicAuth consumer using secret", func() {
-		secret := `
+		ginkgo.It("ApisixRoute with basicAuth consumer using secret", func() {
+			secret := `
 apiVersion: v1
 kind: Secret
 metadata:
@@ -126,36 +115,24 @@ data:
   password: YmFy
   username: Zm9v
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating basic secret for ApisixConsumer")
-
-		ac := `
-apiVersion: apisix.apache.org/v2beta3
-kind: ApisixConsumer
-metadata:
-  name: basicvalue
-spec:
-  authParameter:
-    basicAuth:
-      secretRef:
-        name: basic
-`
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating basicAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		basicAuth, _ := grs[0].Plugins["basic-auth"]
-		assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
-			"username": "foo",
-			"password": "bar",
-		})
-
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating basic secret for ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.ApisixConsumerBasicAuthSecretCreated("basicvalue", "basic"), "creating basicAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			basicAuth, _ := grs[0].Plugins["basic-auth"]
+			assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
+				"username": "foo",
+				"password": "bar",
+			})
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -181,65 +158,54 @@ spec:
      enable: true
      type: basicAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with basicAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("Authorization", "Basic Zm9vOmJhcg==").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "Missing authorization in request")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("Authorization", "Basic Zm9vOmJhcg==").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
-
-	ginkgo.It("ApisixRoute with keyAuth consumer", func() {
-		ac := `
-apiVersion: apisix.apache.org/v2beta3
-kind: ApisixConsumer
-metadata:
-  name: keyvalue
-spec:
-  authParameter:
-    keyAuth:
-      value:
-        key: foo
-`
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		basicAuth, _ := grs[0].Plugins["key-auth"]
-		assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
-			"key": "foo",
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with basicAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("Authorization", "Basic Zm9vOmJhcg==").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "Missing authorization in request")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("Authorization", "Basic Zm9vOmJhcg==").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
 		})
 
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+		ginkgo.It("ApisixRoute with keyAuth consumer", func() {
+			assert.Nil(ginkgo.GinkgoT(), s.ApisixConsumerKeyAuthCreated("keyvalue", "foo"), "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			basicAuth, _ := grs[0].Plugins["key-auth"]
+			assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
+				"key": "foo",
+			})
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -265,39 +231,39 @@ spec:
      enable: true
      type: keyAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with keyAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("apikey", "foo").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "Missing API key found in request")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("apikey", "baz").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with keyAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("apikey", "foo").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "Missing API key found in request")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("apikey", "baz").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
+		})
 
-	ginkgo.It("ApisixRoute with keyAuth consumer using secret", func() {
-		secret := `
+		ginkgo.It("ApisixRoute with keyAuth consumer using secret", func() {
+			secret := `
 apiVersion: v1
 kind: Secret
 metadata:
@@ -305,35 +271,23 @@ metadata:
 data:
   key: Zm9v
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating keyauth secret for ApisixConsumer")
-
-		ac := `
-apiVersion: apisix.apache.org/v2beta3
-kind: ApisixConsumer
-metadata:
-  name: keyvalue
-spec:
-  authParameter:
-    keyAuth:
-      secretRef:
-        name: keyauth
-`
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating keyAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		basicAuth, _ := grs[0].Plugins["key-auth"]
-		assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
-			"key": "foo",
-		})
-
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating keyauth secret for ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.ApisixConsumerKeyAuthSecretCreated("keyvalue", "keyauth"), "creating keyAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			basicAuth, _ := grs[0].Plugins["key-auth"]
+			assert.Equal(ginkgo.GinkgoT(), basicAuth, map[string]interface{}{
+				"key": "foo",
+			})
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -359,44 +313,44 @@ spec:
      enable: true
      type: keyAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with keyAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("apikey", "foo").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "Missing API key found in request")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("apikey", "baz").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with keyAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("apikey", "foo").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "Missing API key found in request")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("apikey", "baz").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
+		})
 
-	ginkgo.It("ApisixRoute with wolfRBAC consumer", func() {
-		_ = s.StartWolfRBACServer()
-		wolfSvr, err := s.GetWolfRBACServerURL()
-		assert.Nil(ginkgo.GinkgoT(), err, "checking wolf-server")
-		defer s.StopWolfRBACServer()
+		ginkgo.It("ApisixRoute with wolfRBAC consumer", func() {
+			_ = s.StartWolfRBACServer()
+			wolfSvr, err := s.GetWolfRBACServerURL()
+			assert.Nil(ginkgo.GinkgoT(), err, "checking wolf-server")
+			defer s.StopWolfRBACServer()
 
-		ac := fmt.Sprintf(`
+			ac := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -409,23 +363,23 @@ spec:
         appid: "test-app"
         header_prefix: "X-"
 `, wolfSvr)
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating wolfRBAC ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		wolfRBAC, _ := grs[0].Plugins["wolf-rbac"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), wolfRBAC, map[string]interface{}{
-			"server":        wolfSvr,
-			"appid":         "test-app",
-			"header_prefix": "X-",
-		})
-		adminSvc, adminPort := s.ApisixAdminServiceAndPort()
-		ar1 := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating wolfRBAC ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			wolfRBAC, _ := grs[0].Plugins["wolf-rbac"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), wolfRBAC, map[string]interface{}{
+				"server":        wolfSvr,
+				"appid":         "test-app",
+				"header_prefix": "X-",
+			})
+			adminSvc, adminPort := s.ApisixAdminServiceAndPort()
+			ar1 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -443,12 +397,12 @@ spec:
     - name: public-api
       enable: true
 `, adminSvc, adminPort)
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar1), "creating ApisixRoute")
-		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(ar1), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
 
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar2 := fmt.Sprintf(`
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar2 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -468,10 +422,10 @@ spec:
      enable: true
      type: wolfRBAC
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "creating ApisixRoute")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
-		payload := []byte(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
+			payload := []byte(`
 {
 	"appid": "test-app",
 	"username": "test",
@@ -479,42 +433,42 @@ spec:
 	"authType": 1
 }
 		`)
-		body := s.NewAPISIXClient().POST("/apisix/plugin/wolf-rbac/login").
-			WithHeader("Content-Type", "application/json").
-			WithBytes(payload).
-			Expect().
-			Status(http.StatusOK).
-			Body().
-			Contains("rbac_token").
-			Raw()
-
-		data := struct {
-			Token string `json:"rbac_token"`
-		}{}
-		_ = json.Unmarshal([]byte(body), &data)
-
-		_ = s.NewAPISIXClient().GET("").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", data.Token).
-			Expect().
-			Status(http.StatusOK)
-
-		msg401 := s.NewAPISIXClient().GET("").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing rbac token in request")
-	})
+			body := s.NewAPISIXClient().POST("/apisix/plugin/wolf-rbac/login").
+				WithHeader("Content-Type", "application/json").
+				WithBytes(payload).
+				Expect().
+				Status(http.StatusOK).
+				Body().
+				Contains("rbac_token").
+				Raw()
+
+			data := struct {
+				Token string `json:"rbac_token"`
+			}{}
+			_ = json.Unmarshal([]byte(body), &data)
+
+			_ = s.NewAPISIXClient().GET("").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", data.Token).
+				Expect().
+				Status(http.StatusOK)
+
+			msg401 := s.NewAPISIXClient().GET("").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing rbac token in request")
+		})
 
-	ginkgo.It("ApisixRoute with wolfRBAC consumer using secret", func() {
-		_ = s.StartWolfRBACServer()
-		wolfSvr, err := s.GetWolfRBACServerURL()
-		assert.Nil(ginkgo.GinkgoT(), err, "checking wolf-server")
-		defer s.StopWolfRBACServer()
+		ginkgo.It("ApisixRoute with wolfRBAC consumer using secret", func() {
+			_ = s.StartWolfRBACServer()
+			wolfSvr, err := s.GetWolfRBACServerURL()
+			assert.Nil(ginkgo.GinkgoT(), err, "checking wolf-server")
+			defer s.StopWolfRBACServer()
 
-		secret := fmt.Sprintf(`
+			secret := fmt.Sprintf(`
 apiVersion: v1
 kind: Secret
 metadata:
@@ -524,9 +478,9 @@ data:
   appid: dGVzdC1hcHA=
   header_prefix: WC0=
 `, base64.StdEncoding.EncodeToString([]byte(wolfSvr)))
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating wolfRBAC secret for ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating wolfRBAC secret for ApisixConsumer")
 
-		ac := `
+			ac := `
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -537,23 +491,23 @@ spec:
       secretRef:
         name: rbac
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating wolfRBAC ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		wolfRBAC, _ := grs[0].Plugins["wolf-rbac"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), wolfRBAC, map[string]interface{}{
-			"server":        wolfSvr,
-			"appid":         "test-app",
-			"header_prefix": "X-",
-		})
-		adminSvc, adminPort := s.ApisixAdminServiceAndPort()
-		ar1 := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating wolfRBAC ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			wolfRBAC, _ := grs[0].Plugins["wolf-rbac"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), wolfRBAC, map[string]interface{}{
+				"server":        wolfSvr,
+				"appid":         "test-app",
+				"header_prefix": "X-",
+			})
+			adminSvc, adminPort := s.ApisixAdminServiceAndPort()
+			ar1 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -571,12 +525,12 @@ spec:
     - name: public-api
       enable: true
 `, adminSvc, adminPort)
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar1), "creating ApisixRoute")
-		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(ar1), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
 
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar2 := fmt.Sprintf(`
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar2 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -596,10 +550,10 @@ spec:
      enable: true
      type: wolfRBAC
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "creating ApisixRoute")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
-		payload := []byte(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
+			payload := []byte(`
 {
 	"appid": "test-app",
 	"username": "test",
@@ -607,37 +561,37 @@ spec:
 	"authType": 1
 }
 		`)
-		body := s.NewAPISIXClient().POST("/apisix/plugin/wolf-rbac/login").
-			WithHeader("Content-Type", "application/json").
-			WithBytes(payload).
-			Expect().
-			Status(http.StatusOK).
-			Body().
-			Contains("rbac_token").
-			Raw()
-
-		data := struct {
-			Token string `json:"rbac_token"`
-		}{}
-		_ = json.Unmarshal([]byte(body), &data)
-
-		_ = s.NewAPISIXClient().GET("").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", data.Token).
-			Expect().
-			Status(http.StatusOK)
-
-		msg401 := s.NewAPISIXClient().GET("").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing rbac token in request")
-	})
+			body := s.NewAPISIXClient().POST("/apisix/plugin/wolf-rbac/login").
+				WithHeader("Content-Type", "application/json").
+				WithBytes(payload).
+				Expect().
+				Status(http.StatusOK).
+				Body().
+				Contains("rbac_token").
+				Raw()
+
+			data := struct {
+				Token string `json:"rbac_token"`
+			}{}
+			_ = json.Unmarshal([]byte(body), &data)
+
+			_ = s.NewAPISIXClient().GET("").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", data.Token).
+				Expect().
+				Status(http.StatusOK)
+
+			msg401 := s.NewAPISIXClient().GET("").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing rbac token in request")
+		})
 
-	ginkgo.It("ApisixRoute with hmacAuth consumer", func() {
-		ac := `
+		ginkgo.It("ApisixRoute with hmacAuth consumer", func() {
+			ac := `
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -651,23 +605,23 @@ spec:
         algorithm: "hmac-sha256"
         clock_skew: 0
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating hmacAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		hmacAuth, _ := grs[0].Plugins["hmac-auth"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), "papa", hmacAuth["access_key"])
-		assert.Equal(ginkgo.GinkgoT(), "fatpa", hmacAuth["secret_key"])
-		assert.Equal(ginkgo.GinkgoT(), "hmac-sha256", hmacAuth["algorithm"])
-		assert.Equal(ginkgo.GinkgoT(), float64(0), hmacAuth["clock_skew"])
-
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating hmacAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			hmacAuth, _ := grs[0].Plugins["hmac-auth"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), "papa", hmacAuth["access_key"])
+			assert.Equal(ginkgo.GinkgoT(), "fatpa", hmacAuth["secret_key"])
+			assert.Equal(ginkgo.GinkgoT(), "hmac-sha256", hmacAuth["algorithm"])
+			assert.Equal(ginkgo.GinkgoT(), float64(0), hmacAuth["clock_skew"])
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -693,47 +647,47 @@ spec:
      enable: true
      type: hmacAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with hmacAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("X-HMAC-SIGNATURE", "l3Uka7E1kxPA/owQ2+OqJUmflRppjD5q8xPcWbyKKrg=").
-			WithHeader("X-HMAC-ACCESS-KEY", "papa").
-			WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
-			WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
-			WithHeader("User-Agent", "curl/7.29.0").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "access key or signature missing")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("X-HMAC-SIGNATURE", "MhGJMkEYFD+98qtvoDPlvCGIUSmmUaw0In/D0vt2Z4E=").
-			WithHeader("X-HMAC-ACCESS-KEY", "papa").
-			WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
-			WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
-			WithHeader("User-Agent", "curl/7.29.0").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with hmacAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("X-HMAC-SIGNATURE", "l3Uka7E1kxPA/owQ2+OqJUmflRppjD5q8xPcWbyKKrg=").
+				WithHeader("X-HMAC-ACCESS-KEY", "papa").
+				WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
+				WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
+				WithHeader("User-Agent", "curl/7.29.0").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "access key or signature missing")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("X-HMAC-SIGNATURE", "MhGJMkEYFD+98qtvoDPlvCGIUSmmUaw0In/D0vt2Z4E=").
+				WithHeader("X-HMAC-ACCESS-KEY", "papa").
+				WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
+				WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
+				WithHeader("User-Agent", "curl/7.29.0").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
+		})
 
-	ginkgo.It("ApisixRoute with hmacAuth consumer using secret", func() {
-		secret := `
+		ginkgo.It("ApisixRoute with hmacAuth consumer using secret", func() {
+			secret := `
 apiVersion: v1
 kind: Secret
 metadata:
@@ -744,9 +698,9 @@ data:
   algorithm: aG1hYy1zaGEyNTY=
   clock_skew: MA==
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating hmac secret for ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating hmac secret for ApisixConsumer")
 
-		ac := `
+			ac := `
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -757,23 +711,23 @@ spec:
       secretRef:
         name: hmac
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating hmacAuth ApisixConsumer")
-
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
-
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		hmacAuth, _ := grs[0].Plugins["hmac-auth"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), "papa", hmacAuth["access_key"])
-		assert.Equal(ginkgo.GinkgoT(), "fatpa", hmacAuth["secret_key"])
-		assert.Equal(ginkgo.GinkgoT(), "hmac-sha256", hmacAuth["algorithm"])
-		assert.Equal(ginkgo.GinkgoT(), float64(0), hmacAuth["clock_skew"])
-
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating hmacAuth ApisixConsumer")
+
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
+
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			hmacAuth, _ := grs[0].Plugins["hmac-auth"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), "papa", hmacAuth["access_key"])
+			assert.Equal(ginkgo.GinkgoT(), "fatpa", hmacAuth["secret_key"])
+			assert.Equal(ginkgo.GinkgoT(), "hmac-sha256", hmacAuth["algorithm"])
+			assert.Equal(ginkgo.GinkgoT(), float64(0), hmacAuth["clock_skew"])
+
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -799,47 +753,47 @@ spec:
      enable: true
      type: hmacAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with hmacAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			WithHeader("X-HMAC-SIGNATURE", "l3Uka7E1kxPA/owQ2+OqJUmflRppjD5q8xPcWbyKKrg=").
-			WithHeader("X-HMAC-ACCESS-KEY", "papa").
-			WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
-			WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
-			WithHeader("User-Agent", "curl/7.29.0").
-			Expect().
-			Status(http.StatusOK)
-
-		msg := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "access key or signature missing")
-
-		msg = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "baz").
-			WithHeader("X-HMAC-SIGNATURE", "MhGJMkEYFD+98qtvoDPlvCGIUSmmUaw0In/D0vt2Z4E=").
-			WithHeader("X-HMAC-ACCESS-KEY", "papa").
-			WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
-			WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
-			WithHeader("User-Agent", "curl/7.29.0").
-			Expect().
-			Status(http.StatusNotFound).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute with hmacAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				WithHeader("X-HMAC-SIGNATURE", "l3Uka7E1kxPA/owQ2+OqJUmflRppjD5q8xPcWbyKKrg=").
+				WithHeader("X-HMAC-ACCESS-KEY", "papa").
+				WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
+				WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
+				WithHeader("User-Agent", "curl/7.29.0").
+				Expect().
+				Status(http.StatusOK)
+
+			msg := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "access key or signature missing")
+
+			msg = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "baz").
+				WithHeader("X-HMAC-SIGNATURE", "MhGJMkEYFD+98qtvoDPlvCGIUSmmUaw0In/D0vt2Z4E=").
+				WithHeader("X-HMAC-ACCESS-KEY", "papa").
+				WithHeader("X-HMAC-ALGORITHM", "hmac-sha256").
+				WithHeader("X-HMAC-SIGNED-HEADERS", "User-Agent;X-Foo").
+				WithHeader("User-Agent", "curl/7.29.0").
+				Expect().
+				Status(http.StatusNotFound).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg, "404 Route Not Found")
+		})
 
-	ginkgo.It("ApisixRoute with jwtAuth consumer", func() {
-		ac := `
+		ginkgo.It("ApisixRoute with jwtAuth consumer", func() {
+			ac := `
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -850,20 +804,20 @@ spec:
       value:
         key: foo-key
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating jwtAuth ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating jwtAuth ApisixConsumer")
 
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
 
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		jwtAuth, _ := grs[0].Plugins["jwt-auth"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), jwtAuth["key"], "foo-key")
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			jwtAuth, _ := grs[0].Plugins["jwt-auth"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), jwtAuth["key"], "foo-key")
 
-		adminSvc, adminPort := s.ApisixAdminServiceAndPort()
-		ar1 := fmt.Sprintf(`
+			adminSvc, adminPort := s.ApisixAdminServiceAndPort()
+			ar1 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -881,12 +835,12 @@ spec:
     - name: public-api
       enable: true
 `, adminSvc, adminPort)
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar1), "creating ApisixRoute")
-		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(ar1), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
 
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar2 := fmt.Sprintf(`
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar2 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -906,35 +860,35 @@ spec:
      enable: true
      type: jwtAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "Creating ApisixRoute with jwtAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing JWT token in request")
-
-		token := s.NewAPISIXClient().GET("/apisix/plugin/jwt/sign").
-			WithQuery("key", "foo-key").
-			Expect().
-			Status(http.StatusOK).
-			Body().
-			NotEmpty().
-			Raw()
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", string(token)).
-			Expect().
-			Status(http.StatusOK)
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "Creating ApisixRoute with jwtAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing JWT token in request")
+
+			token := s.NewAPISIXClient().GET("/apisix/plugin/jwt/sign").
+				WithQuery("key", "foo-key").
+				Expect().
+				Status(http.StatusOK).
+				Body().
+				NotEmpty().
+				Raw()
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", string(token)).
+				Expect().
+				Status(http.StatusOK)
+		})
 
-	ginkgo.It("ApisixRoute with jwtAuth consumer using secret", func() {
-		secret := `
+		ginkgo.It("ApisixRoute with jwtAuth consumer using secret", func() {
+			secret := `
 apiVersion: v1
 kind: Secret
 metadata:
@@ -942,9 +896,9 @@ metadata:
 data:
   key: Zm9vLWtleQ==
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating jwtAuth secret for ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating jwtAuth secret for ApisixConsumer")
 
-		ac := `
+			ac := `
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixConsumer
 metadata:
@@ -955,20 +909,20 @@ spec:
       secretRef:
         name: jwt
 `
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac), "creating jwtAuth ApisixConsumer")
+			assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixConsumer(ac), "creating jwtAuth ApisixConsumer")
 
-		// Wait until the ApisixConsumer create event was delivered.
-		time.Sleep(6 * time.Second)
+			// Wait until the ApisixConsumer create event was delivered.
+			time.Sleep(6 * time.Second)
 
-		grs, err := s.ListApisixConsumers()
-		assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
-		assert.Len(ginkgo.GinkgoT(), grs, 1)
-		assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
-		jwtAuth, _ := grs[0].Plugins["jwt-auth"].(map[string]interface{})
-		assert.Equal(ginkgo.GinkgoT(), jwtAuth["key"], "foo-key")
+			grs, err := s.ListApisixConsumers()
+			assert.Nil(ginkgo.GinkgoT(), err, "listing consumer")
+			assert.Len(ginkgo.GinkgoT(), grs, 1)
+			assert.Len(ginkgo.GinkgoT(), grs[0].Plugins, 1)
+			jwtAuth, _ := grs[0].Plugins["jwt-auth"].(map[string]interface{})
+			assert.Equal(ginkgo.GinkgoT(), jwtAuth["key"], "foo-key")
 
-		adminSvc, adminPort := s.ApisixAdminServiceAndPort()
-		ar1 := fmt.Sprintf(`
+			adminSvc, adminPort := s.ApisixAdminServiceAndPort()
+			ar1 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -986,12 +940,12 @@ spec:
     - name: public-api
       enable: true
 `, adminSvc, adminPort)
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar1), "creating ApisixRoute")
-		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(ar1), "creating ApisixRoute")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
 
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar2 := fmt.Sprintf(`
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar2 := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -1011,36 +965,36 @@ spec:
      enable: true
      type: jwtAuth
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "Creating ApisixRoute with jwtAuth")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
-
-		msg401 := s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			Expect().
-			Status(http.StatusUnauthorized).
-			Body().
-			Raw()
-		assert.Contains(ginkgo.GinkgoT(), msg401, "Missing JWT token in request")
-
-		token := s.NewAPISIXClient().GET("/apisix/plugin/jwt/sign").
-			WithQuery("key", "foo-key").
-			Expect().
-			Status(http.StatusOK).
-			Body().
-			NotEmpty().
-			Raw()
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("Authorization", string(token)).
-			Expect().
-			Status(http.StatusOK)
-	})
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar2), "Creating ApisixRoute with jwtAuth")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(2), "Checking number of upstreams")
+
+			msg401 := s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				Expect().
+				Status(http.StatusUnauthorized).
+				Body().
+				Raw()
+			assert.Contains(ginkgo.GinkgoT(), msg401, "Missing JWT token in request")
+
+			token := s.NewAPISIXClient().GET("/apisix/plugin/jwt/sign").
+				WithQuery("key", "foo-key").
+				Expect().
+				Status(http.StatusOK).
+				Body().
+				NotEmpty().
+				Raw()
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("Authorization", string(token)).
+				Expect().
+				Status(http.StatusOK)
+		})
 
-	ginkgo.It("ApisixRoute without authentication", func() {
-		backendSvc, backendPorts := s.DefaultHTTPBackend()
-		ar := fmt.Sprintf(`
+		ginkgo.It("ApisixRoute without authentication", func() {
+			backendSvc, backendPorts := s.DefaultHTTPBackend()
+			ar := fmt.Sprintf(`
 apiVersion: apisix.apache.org/v2beta3
 kind: ApisixRoute
 metadata:
@@ -1065,14 +1019,22 @@ spec:
    authentication:
      enable: false
 `, backendSvc, backendPorts[0])
-		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute without authentication")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
-		assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
-
-		_ = s.NewAPISIXClient().GET("/ip").
-			WithHeader("Host", "httpbin.org").
-			WithHeader("X-Foo", "bar").
-			Expect().
-			Status(http.StatusOK)
+			assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ar), "creating ApisixRoute without authentication")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1), "Checking number of routes")
+			assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixUpstreamsCreated(1), "Checking number of upstreams")
+
+			_ = s.NewAPISIXClient().GET("/ip").
+				WithHeader("Host", "httpbin.org").
+				WithHeader("X-Foo", "bar").
+				Expect().
+				Status(http.StatusOK)
+		})
+	}
+
+	ginkgo.Describe("suite-features: scaffold v2beta3", func() {
+		suites(scaffold.NewDefaultScaffold)
+	})
+	ginkgo.Describe("suite-features: scaffold v2", func() {
+		suites(scaffold.NewDefaultV2Scaffold)
 	})
 })