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 f6f0a3b5 feat: support ApisixConsumer v2 (#989)
f6f0a3b5 is described below

commit f6f0a3b5552ba8fda556e0edb9296c1c0a4c3e31
Author: Sarasa Kisaragi <[email protected]>
AuthorDate: Mon May 23 17:09:56 2022 +0800

    feat: support ApisixConsumer v2 (#989)
---
 cmd/ingress/ingress.go                       |   1 +
 pkg/config/config.go                         |   2 +
 pkg/config/config_test.go                    |   2 +
 pkg/ingress/apisix_consumer.go               | 158 ++++++++++++++++++-------
 pkg/ingress/compare.go                       |   2 +-
 pkg/ingress/controller.go                    |  17 ++-
 pkg/ingress/status.go                        |  17 +++
 pkg/kube/apisix_consumer.go                  | 169 +++++++++++++++++++++++++++
 pkg/kube/translation/apisix_consumer.go      |  48 +++++++-
 pkg/kube/translation/apisix_consumer_test.go | 116 +++++++++++++++++-
 pkg/kube/translation/plugin.go               | 123 ++++++++++++++++++-
 pkg/kube/translation/plugin_test.go          |  54 ++++-----
 pkg/kube/translation/translator.go           |   7 +-
 13 files changed, 630 insertions(+), 86 deletions(-)

diff --git a/cmd/ingress/ingress.go b/cmd/ingress/ingress.go
index d0a24be5..daed1637 100644
--- a/cmd/ingress/ingress.go
+++ b/cmd/ingress/ingress.go
@@ -164,6 +164,7 @@ For example, no available LB exists in the bare metal 
environment.`)
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.ApisixRouteVersion, 
"apisix-route-version", config.ApisixRouteV2beta3, "the supported apisixroute 
api group version, can be \"apisix.apache.org/v2beta2\" or 
\"apisix.apache.org/v2beta3\"")
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.ApisixTlsVersion, 
"apisix-tls-version", config.ApisixV2beta3, "the supported apisixtls api group 
version, can be \"apisix.apache.org/v2beta3\" or \"apisix.apache.org/v2\"")
        
cmd.PersistentFlags().StringVar(&cfg.Kubernetes.ApisixClusterConfigVersion, 
"apisix-cluster-config-version", config.ApisixV2beta3, "the supported 
ApisixClusterConfig api group version, can be \"apisix.apache.org/v2beta3\" or 
\"apisix.apache.org/v2\"")
+       cmd.PersistentFlags().StringVar(&cfg.Kubernetes.ApisixConsumerVersion, 
"apisix-consumer-version", config.ApisixV2beta3, "the supported ApisixConsumer 
api group version, can be \"apisix.apache.org/v2beta3\" or 
\"apisix.apache.org/v2\"")
        cmd.PersistentFlags().BoolVar(&cfg.Kubernetes.WatchEndpointSlices, 
"watch-endpointslices", false, "whether to watch endpointslices rather than 
endpoints")
        cmd.PersistentFlags().BoolVar(&cfg.Kubernetes.EnableGatewayAPI, 
"enable-gateway-api", false, "whether to enable support for Gateway API")
        cmd.PersistentFlags().StringVar(&cfg.APISIX.DefaultClusterBaseURL, 
"default-apisix-cluster-base-url", "", "the base URL of admin api / manager api 
for the default APISIX cluster")
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 15b1d10a..2641ef5d 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -96,6 +96,7 @@ type KubernetesConfig struct {
        IngressVersion             string             `json:"ingress_version" 
yaml:"ingress_version"`
        WatchEndpointSlices        bool               
`json:"watch_endpoint_slices" yaml:"watch_endpoint_slices"`
        ApisixRouteVersion         string             
`json:"apisix_route_version" yaml:"apisix_route_version"`
+       ApisixConsumerVersion      string             
`json:"apisix_consumer_version" yaml:"apisix_consumer_version"`
        ApisixTlsVersion           string             
`json:"apisix_tls_version" yaml:"apisix_tls_version"`
        ApisixClusterConfigVersion string             
`json:"apisix_cluster_config_version" yaml:"apisix_cluster_config_version"`
        EnableGatewayAPI           bool               
`json:"enable_gateway_api" yaml:"enable_gateway_api"`
@@ -133,6 +134,7 @@ func NewDefaultConfig() *Config {
                        IngressClass:               IngressClass,
                        IngressVersion:             IngressNetworkingV1,
                        ApisixRouteVersion:         ApisixRouteV2beta3,
+                       ApisixConsumerVersion:      ApisixV2beta3,
                        ApisixTlsVersion:           ApisixV2beta3,
                        ApisixClusterConfigVersion: ApisixV2beta3,
                        WatchEndpointSlices:        false,
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 515d8e6a..311afd50 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -45,6 +45,7 @@ func TestNewConfigFromFile(t *testing.T) {
                        IngressClass:               IngressClass,
                        IngressVersion:             IngressNetworkingV1,
                        ApisixRouteVersion:         ApisixRouteV2beta3,
+                       ApisixConsumerVersion:      ApisixV2beta3,
                        ApisixTlsVersion:           ApisixV2beta3,
                        ApisixClusterConfigVersion: ApisixV2beta3,
                },
@@ -128,6 +129,7 @@ func TestConfigWithEnvVar(t *testing.T) {
                        IngressClass:               IngressClass,
                        IngressVersion:             IngressNetworkingV1,
                        ApisixRouteVersion:         ApisixRouteV2beta3,
+                       ApisixConsumerVersion:      ApisixV2beta3,
                        ApisixTlsVersion:           ApisixV2beta3,
                        ApisixClusterConfigVersion: ApisixV2beta3,
                },
diff --git a/pkg/ingress/apisix_consumer.go b/pkg/ingress/apisix_consumer.go
index edc9b78e..8a456a70 100644
--- a/pkg/ingress/apisix_consumer.go
+++ b/pkg/ingress/apisix_consumer.go
@@ -16,6 +16,7 @@ package ingress
 
 import (
        "context"
+       "fmt"
        "time"
 
        "go.uber.org/zap"
@@ -25,7 +26,8 @@ import (
        "k8s.io/client-go/tools/cache"
        "k8s.io/client-go/util/workqueue"
 
-       configv2beta3 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2beta3"
+       "github.com/apache/apisix-ingress-controller/pkg/config"
+       "github.com/apache/apisix-ingress-controller/pkg/kube"
        "github.com/apache/apisix-ingress-controller/pkg/log"
        "github.com/apache/apisix-ingress-controller/pkg/types"
 )
@@ -79,62 +81,113 @@ func (c *apisixConsumerController) runWorker(ctx 
context.Context) {
 }
 
 func (c *apisixConsumerController) sync(ctx context.Context, ev *types.Event) 
error {
-       key := ev.Object.(string)
+       event := ev.Object.(kube.ApisixConsumerEvent)
+       key := event.Key
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
        if err != nil {
                log.Errorf("found ApisixConsumer resource with invalid meta 
namespace key %s: %s", key, err)
                return err
        }
 
-       ac, err := 
c.controller.apisixConsumerLister.ApisixConsumers(namespace).Get(name)
+       var multiVersioned kube.ApisixConsumer
+       switch event.GroupVersion {
+       case config.ApisixV2beta3:
+               multiVersioned, err = 
c.controller.apisixConsumerLister.V2beta3(namespace, name)
+       case config.ApisixV2:
+               multiVersioned, err = 
c.controller.apisixConsumerLister.V2(namespace, name)
+       default:
+               return fmt.Errorf("unsupported ApisixConsumer group version 
%s", event.GroupVersion)
+       }
+
        if err != nil {
                if !k8serrors.IsNotFound(err) {
-                       log.Errorf("failed to get ApisixConsumer %s: %s", key, 
err)
+                       log.Errorw("failed to get ApisixConsumer",
+                               zap.Error(err),
+                               zap.String("key", key),
+                               zap.String("version", event.GroupVersion),
+                       )
                        return err
                }
                if ev.Type != types.EventDelete {
-                       log.Warnf("ApisixConsumer %s was deleted before it can 
be delivered", key)
+                       log.Warnw("ApisixConsumer was deleted before it can be 
delivered",
+                               zap.String("key", key),
+                               zap.String("version", event.GroupVersion),
+                       )
                        // Don't need to retry.
                        return nil
                }
        }
        if ev.Type == types.EventDelete {
-               if ac != nil {
+               if multiVersioned != nil {
                        // We still find the resource while we are processing 
the DELETE event,
                        // that means object with same namespace and name was 
created, discarding
                        // this stale DELETE event.
                        log.Warnf("discard the stale ApisixConsumer delete 
event since the %s exists", key)
                        return nil
                }
-               ac = ev.Tombstone.(*configv2beta3.ApisixConsumer)
+               multiVersioned = ev.Tombstone.(kube.ApisixConsumer)
        }
 
-       consumer, err := c.controller.translator.TranslateApisixConsumer(ac)
-       if err != nil {
-               log.Errorw("failed to translate ApisixConsumer",
-                       zap.Error(err),
+       switch event.GroupVersion {
+       case config.ApisixV2beta3:
+               ac := multiVersioned.V2beta3()
+
+               consumer, err := 
c.controller.translator.TranslateApisixConsumerV2beta3(ac)
+               if err != nil {
+                       log.Errorw("failed to translate ApisixConsumer",
+                               zap.Error(err),
+                               zap.Any("ApisixConsumer", ac),
+                       )
+                       c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
+                       c.controller.recordStatus(ac, _resourceSyncAborted, 
err, metav1.ConditionFalse, ac.GetGeneration())
+                       return err
+               }
+               log.Debugw("got consumer object from ApisixConsumer",
+                       zap.Any("consumer", consumer),
                        zap.Any("ApisixConsumer", ac),
                )
-               c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
-               c.controller.recordStatus(ac, _resourceSyncAborted, err, 
metav1.ConditionFalse, ac.GetGeneration())
-               return err
-       }
-       log.Debug("got consumer object from ApisixConsumer",
-               zap.Any("consumer", consumer),
-               zap.Any("ApisixConsumer", ac),
-       )
 
-       if err := c.controller.syncConsumer(ctx, consumer, ev.Type); err != nil 
{
-               log.Errorw("failed to sync Consumer to APISIX",
-                       zap.Error(err),
+               if err := c.controller.syncConsumer(ctx, consumer, ev.Type); 
err != nil {
+                       log.Errorw("failed to sync Consumer to APISIX",
+                               zap.Error(err),
+                               zap.Any("consumer", consumer),
+                       )
+                       c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
+                       c.controller.recordStatus(ac, _resourceSyncAborted, 
err, metav1.ConditionFalse, ac.GetGeneration())
+                       return err
+               }
+
+               c.controller.recorderEvent(ac, corev1.EventTypeNormal, 
_resourceSynced, nil)
+       case config.ApisixV2:
+               ac := multiVersioned.V2()
+
+               consumer, err := 
c.controller.translator.TranslateApisixConsumerV2(ac)
+               if err != nil {
+                       log.Errorw("failed to translate ApisixConsumer",
+                               zap.Error(err),
+                               zap.Any("ApisixConsumer", ac),
+                       )
+                       c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
+                       c.controller.recordStatus(ac, _resourceSyncAborted, 
err, metav1.ConditionFalse, ac.GetGeneration())
+                       return err
+               }
+               log.Debugw("got consumer object from ApisixConsumer",
                        zap.Any("consumer", consumer),
+                       zap.Any("ApisixConsumer", ac),
                )
-               c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
-               c.controller.recordStatus(ac, _resourceSyncAborted, err, 
metav1.ConditionFalse, ac.GetGeneration())
-               return err
-       }
 
-       c.controller.recorderEvent(ac, corev1.EventTypeNormal, _resourceSynced, 
nil)
+               if err := c.controller.syncConsumer(ctx, consumer, ev.Type); 
err != nil {
+                       log.Errorw("failed to sync Consumer to APISIX",
+                               zap.Error(err),
+                               zap.Any("consumer", consumer),
+                       )
+                       c.controller.recorderEvent(ac, corev1.EventTypeWarning, 
_resourceSyncAborted, err)
+                       c.controller.recordStatus(ac, _resourceSyncAborted, 
err, metav1.ConditionFalse, ac.GetGeneration())
+                       return err
+               }
+
+               c.controller.recorderEvent(ac, corev1.EventTypeNormal, 
_resourceSynced, nil)
+       }
        return nil
 }
 
@@ -162,6 +215,11 @@ func (c *apisixConsumerController) handleSyncErr(obj 
interface{}, err error) {
 }
 
 func (c *apisixConsumerController) onAdd(obj interface{}) {
+       ac, err := kube.NewApisixConsumer(obj)
+       if err != nil {
+               log.Errorw("found ApisixConsumer resource with bad type", 
zap.Error(err))
+               return
+       }
        key, err := cache.MetaNamespaceKeyFunc(obj)
        if err != nil {
                log.Errorf("found ApisixConsumer resource with bad meta 
namespace key: %s", err)
@@ -175,17 +233,28 @@ func (c *apisixConsumerController) onAdd(obj interface{}) 
{
        )
 
        c.workqueue.Add(&types.Event{
-               Type:   types.EventAdd,
-               Object: key,
+               Type: types.EventAdd,
+               Object: kube.ApisixConsumerEvent{
+                       Key:          key,
+                       GroupVersion: ac.GroupVersion(),
+               },
        })
 
        c.controller.MetricsCollector.IncrEvents("consumer", "add")
 }
 
 func (c *apisixConsumerController) onUpdate(oldObj, newObj interface{}) {
-       prev := oldObj.(*configv2beta3.ApisixConsumer)
-       curr := newObj.(*configv2beta3.ApisixConsumer)
-       if prev.ResourceVersion >= curr.ResourceVersion {
+       prev, err := kube.NewApisixConsumer(oldObj)
+       if err != nil {
+               log.Errorw("found ApisixConsumer resource with bad type", 
zap.Error(err))
+               return
+       }
+       curr, err := kube.NewApisixConsumer(newObj)
+       if err != nil {
+               log.Errorw("found ApisixConsumer resource with bad type", 
zap.Error(err))
+               return
+       }
+       if prev.ResourceVersion() >= curr.ResourceVersion() {
                return
        }
        key, err := cache.MetaNamespaceKeyFunc(newObj)
@@ -202,21 +271,29 @@ func (c *apisixConsumerController) onUpdate(oldObj, 
newObj interface{}) {
        )
 
        c.workqueue.Add(&types.Event{
-               Type:   types.EventUpdate,
-               Object: key,
+               Type: types.EventUpdate,
+               Object: kube.ApisixConsumerEvent{
+                       Key:          key,
+                       OldObject:    prev,
+                       GroupVersion: curr.GroupVersion(),
+               },
        })
 
        c.controller.MetricsCollector.IncrEvents("consumer", "update")
 }
 
 func (c *apisixConsumerController) onDelete(obj interface{}) {
-       ac, ok := obj.(*configv2beta3.ApisixConsumer)
-       if !ok {
+       ac, err := kube.NewApisixConsumer(obj)
+       if err != nil {
                tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
                if !ok {
                        return
                }
-               ac = tombstone.Obj.(*configv2beta3.ApisixConsumer)
+               ac, err = kube.NewApisixConsumer(tombstone.Obj)
+               if err != nil {
+                       log.Errorw("found ApisixConsumer resource with bad 
type", zap.Error(err))
+                       return
+               }
        }
 
        key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
@@ -231,8 +308,11 @@ func (c *apisixConsumerController) onDelete(obj 
interface{}) {
                zap.Any("final state", ac),
        )
        c.workqueue.Add(&types.Event{
-               Type:      types.EventDelete,
-               Object:    key,
+               Type: types.EventDelete,
+               Object: kube.ApisixConsumerEvent{
+                       Key:          key,
+                       GroupVersion: ac.GroupVersion(),
+               },
                Tombstone: ac,
        })
 
diff --git a/pkg/ingress/compare.go b/pkg/ingress/compare.go
index 6d2f560d..6ab081e4 100644
--- a/pkg/ingress/compare.go
+++ b/pkg/ingress/compare.go
@@ -130,7 +130,7 @@ func (c *Controller) CompareResources(ctx context.Context) 
error {
                                ctx.Done()
                        } else {
                                for _, con := range retConsumer.Items {
-                                       consumer, err := 
c.translator.TranslateApisixConsumer(&con)
+                                       consumer, err := 
c.translator.TranslateApisixConsumerV2beta3(&con)
                                        if err != nil {
                                                log.Error(err.Error())
                                                ctx.Done()
diff --git a/pkg/ingress/controller.go b/pkg/ingress/controller.go
index c1afded2..33c273c8 100644
--- a/pkg/ingress/controller.go
+++ b/pkg/ingress/controller.go
@@ -114,7 +114,7 @@ type Controller struct {
        apisixClusterConfigLister   kube.ApisixClusterConfigLister
        apisixClusterConfigInformer cache.SharedIndexInformer
        apisixConsumerInformer      cache.SharedIndexInformer
-       apisixConsumerLister        listersv2beta3.ApisixConsumerLister
+       apisixConsumerLister        kube.ApisixConsumerLister
        apisixPluginConfigInformer  cache.SharedIndexInformer
        apisixPluginConfigLister    kube.ApisixPluginConfigLister
        gatewayInformer             cache.SharedIndexInformer
@@ -204,6 +204,7 @@ func (c *Controller) initWhenStartLeading() {
                apisixRouteInformer         cache.SharedIndexInformer
                apisixTlsInformer           cache.SharedIndexInformer
                apisixClusterConfigInformer cache.SharedIndexInformer
+               apisixConsumerInformer      cache.SharedIndexInformer
        )
 
        kubeFactory := c.kubeClient.NewSharedIndexInformerFactory()
@@ -234,7 +235,10 @@ func (c *Controller) initWhenStartLeading() {
                
apisixFactory.Apisix().V2beta3().ApisixClusterConfigs().Lister(),
                apisixFactory.Apisix().V2().ApisixClusterConfigs().Lister(),
        )
-       c.apisixConsumerLister = 
apisixFactory.Apisix().V2beta3().ApisixConsumers().Lister()
+       c.apisixConsumerLister = kube.NewApisixConsumerLister(
+               apisixFactory.Apisix().V2beta3().ApisixConsumers().Lister(),
+               apisixFactory.Apisix().V2().ApisixConsumers().Lister(),
+       )
        c.apisixPluginConfigLister = kube.NewApisixPluginConfigLister(
                apisixFactory.Apisix().V2beta3().ApisixPluginConfigs().Lister(),
        )
@@ -289,6 +293,13 @@ func (c *Controller) initWhenStartLeading() {
                panic(fmt.Errorf("unsupported ApisixClusterConfig version %v", 
c.cfg.Kubernetes.ApisixClusterConfigVersion))
        }
 
+       switch c.cfg.Kubernetes.ApisixConsumerVersion {
+       case config.ApisixRouteV2beta3:
+               apisixConsumerInformer = 
apisixFactory.Apisix().V2beta3().ApisixConsumers().Informer()
+       case config.ApisixRouteV2:
+               apisixConsumerInformer = 
apisixFactory.Apisix().V2().ApisixConsumers().Informer()
+       }
+
        c.namespaceInformer = kubeFactory.Core().V1().Namespaces().Informer()
        c.podInformer = kubeFactory.Core().V1().Pods().Informer()
        c.svcInformer = kubeFactory.Core().V1().Services().Informer()
@@ -298,7 +309,7 @@ func (c *Controller) initWhenStartLeading() {
        c.apisixClusterConfigInformer = apisixClusterConfigInformer
        c.secretInformer = kubeFactory.Core().V1().Secrets().Informer()
        c.apisixTlsInformer = apisixTlsInformer
-       c.apisixConsumerInformer = 
apisixFactory.Apisix().V2beta3().ApisixConsumers().Informer()
+       c.apisixConsumerInformer = apisixConsumerInformer
        c.apisixPluginConfigInformer = 
apisixFactory.Apisix().V2beta3().ApisixPluginConfigs().Informer()
 
        if c.cfg.Kubernetes.WatchEndpointSlices {
diff --git a/pkg/ingress/status.go b/pkg/ingress/status.go
index c2d090ed..604227a0 100644
--- a/pkg/ingress/status.go
+++ b/pkg/ingress/status.go
@@ -177,6 +177,23 @@ func (c *Controller) recordStatus(at interface{}, reason 
string, err error, stat
                                )
                        }
                }
+       case *configv2.ApisixConsumer:
+               // set to status
+               if v.Status.Conditions == nil {
+                       conditions := make([]metav1.Condition, 0)
+                       v.Status.Conditions = conditions
+               }
+               if c.verifyGeneration(&v.Status.Conditions, condition) {
+                       meta.SetStatusCondition(&v.Status.Conditions, condition)
+                       if _, errRecord := 
client.ApisixV2().ApisixConsumers(v.Namespace).
+                               UpdateStatus(context.TODO(), v, 
metav1.UpdateOptions{}); errRecord != nil {
+                               log.Errorw("failed to record status change for 
ApisixConsumer",
+                                       zap.Error(errRecord),
+                                       zap.String("name", v.Name),
+                                       zap.String("namespace", v.Namespace),
+                               )
+                       }
+               }
        case *configv2beta3.ApisixPluginConfig:
                // set to status
                if v.Status.Conditions == nil {
diff --git a/pkg/kube/apisix_consumer.go b/pkg/kube/apisix_consumer.go
new file mode 100644
index 00000000..a9d188d9
--- /dev/null
+++ b/pkg/kube/apisix_consumer.go
@@ -0,0 +1,169 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package kube
+
+import (
+       "errors"
+
+       "github.com/apache/apisix-ingress-controller/pkg/config"
+       configv2 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2"
+       configv2beta3 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2beta3"
+       listersv2 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/listers/config/v2"
+       listersv2beta3 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/listers/config/v2beta3"
+)
+
+// ApisixConsumerLister is an encapsulation for the lister of ApisixConsumer,
+// it aims at to be compatible with different ApisixConsumer versions.
+type ApisixConsumerLister interface {
+       // V2beta3 gets the ApisixConsumer in apisix.apache.org/v2beta3.
+       V2beta3(string, string) (ApisixConsumer, error)
+       // V2 gets the ApisixConsumer in apisix.apache.org/v2.
+       V2(string, string) (ApisixConsumer, error)
+}
+
+// ApisixConsumerInformer is an encapsulation for the informer of 
ApisixConsumer,
+// it aims at to be compatible with different ApisixConsumer versions.
+type ApisixConsumerInformer interface {
+       Run(chan struct{})
+}
+
+// ApisixConsumer is an encapsulation for ApisixConsumer resource with 
different
+// versions, for now, they are apisix.apache.org/v2beta3 and 
apisix.apache.org/v2
+type ApisixConsumer interface {
+       // GroupVersion returns the api group version of the
+       // real ApisixConsumer.
+       GroupVersion() string
+       // V2beta3 returns the ApisixConsumer in apisix.apache.org/v2beta3, the 
real
+       // ApisixConsumer must be in this group version, otherwise will panic.
+       V2beta3() *configv2beta3.ApisixConsumer
+       // V2 returns the ApisixConsumer in apisix.apache.org/v2, the real
+       // ApisixConsumer must be in this group version, otherwise will panic.
+       V2() *configv2.ApisixConsumer
+       // ResourceVersion returns the the resource version field inside
+       // the real ApisixConsumer.
+       ResourceVersion() string
+}
+
+// ApisixConsumerEvent contains the ApisixConsumer key (namespace/name)
+// and the group version message.
+type ApisixConsumerEvent struct {
+       Key          string
+       OldObject    ApisixConsumer
+       GroupVersion string
+}
+
+type apisixConsumer struct {
+       groupVersion string
+       v2beta3      *configv2beta3.ApisixConsumer
+       v2           *configv2.ApisixConsumer
+}
+
+func (ac *apisixConsumer) V2beta3() *configv2beta3.ApisixConsumer {
+       if ac.groupVersion != config.ApisixV2beta3 {
+               panic("not a apisix.apache.org/v2beta3 Consumer")
+       }
+       return ac.v2beta3
+}
+
+func (ac *apisixConsumer) V2() *configv2.ApisixConsumer {
+       if ac.groupVersion != config.ApisixV2 {
+               panic("not a apisix.apache.org/v2 Consumer")
+       }
+       return ac.v2
+}
+
+func (ac *apisixConsumer) GroupVersion() string {
+       return ac.groupVersion
+}
+
+func (ac *apisixConsumer) ResourceVersion() string {
+       if ac.groupVersion == config.ApisixV2beta3 {
+               return ac.V2beta3().ResourceVersion
+       }
+       return ac.V2().ResourceVersion
+}
+
+type apisixConsumerLister struct {
+       v2beta3Lister listersv2beta3.ApisixConsumerLister
+       v2Lister      listersv2.ApisixConsumerLister
+}
+
+func (l *apisixConsumerLister) V2beta3(namespace, name string) 
(ApisixConsumer, error) {
+       ac, err := l.v2beta3Lister.ApisixConsumers(namespace).Get(name)
+       if err != nil {
+               return nil, err
+       }
+       return &apisixConsumer{
+               groupVersion: config.ApisixV2beta3,
+               v2beta3:      ac,
+       }, nil
+}
+
+func (l *apisixConsumerLister) V2(namespace, name string) (ApisixConsumer, 
error) {
+       ac, err := l.v2Lister.ApisixConsumers(namespace).Get(name)
+       if err != nil {
+               return nil, err
+       }
+       return &apisixConsumer{
+               groupVersion: config.ApisixV2,
+               v2:           ac,
+       }, nil
+}
+
+// MustNewApisixConsumer creates a kube.ApisixConsumer object according to the
+// type of obj.
+func MustNewApisixConsumer(obj interface{}) ApisixConsumer {
+       switch ac := obj.(type) {
+       case *configv2beta3.ApisixConsumer:
+               return &apisixConsumer{
+                       groupVersion: config.ApisixV2beta3,
+                       v2beta3:      ac,
+               }
+       case *configv2.ApisixConsumer:
+               return &apisixConsumer{
+                       groupVersion: config.ApisixV2,
+                       v2:           ac,
+               }
+       default:
+               panic("invalid ApisixConsumer type")
+       }
+}
+
+// NewApisixConsumer creates a kube.ApisixConsumer object according to the
+// type of obj. It returns nil and the error reason when the
+// type assertion fails.
+func NewApisixConsumer(obj interface{}) (ApisixConsumer, error) {
+       switch ac := obj.(type) {
+       case *configv2beta3.ApisixConsumer:
+               return &apisixConsumer{
+                       groupVersion: config.ApisixV2beta3,
+                       v2beta3:      ac,
+               }, nil
+       case *configv2.ApisixConsumer:
+               return &apisixConsumer{
+                       groupVersion: config.ApisixV2,
+                       v2:           ac,
+               }, nil
+       default:
+               return nil, errors.New("invalid ApisixConsumer type")
+       }
+}
+
+func NewApisixConsumerLister(v2beta3 listersv2beta3.ApisixConsumerLister, v2 
listersv2.ApisixConsumerLister) ApisixConsumerLister {
+       return &apisixConsumerLister{
+               v2beta3Lister: v2beta3,
+               v2Lister:      v2,
+       }
+}
diff --git a/pkg/kube/translation/apisix_consumer.go 
b/pkg/kube/translation/apisix_consumer.go
index 04525799..982b741f 100644
--- a/pkg/kube/translation/apisix_consumer.go
+++ b/pkg/kube/translation/apisix_consumer.go
@@ -17,35 +17,73 @@ package translation
 import (
        "fmt"
 
+       configv2 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2"
        configv2beta3 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2beta3"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
 
-func (t *translator) TranslateApisixConsumer(ac *configv2beta3.ApisixConsumer) 
(*apisixv1.Consumer, error) {
+func (t *translator) TranslateApisixConsumerV2beta3(ac 
*configv2beta3.ApisixConsumer) (*apisixv1.Consumer, error) {
        // As the CRD schema ensures that only one authN can be configured,
        // so here the order is no matter.
 
        plugins := make(apisixv1.Plugins)
        if ac.Spec.AuthParameter.KeyAuth != nil {
-               cfg, err := t.translateConsumerKeyAuthPlugin(ac.Namespace, 
ac.Spec.AuthParameter.KeyAuth)
+               cfg, err := 
t.translateConsumerKeyAuthPluginV2beta3(ac.Namespace, 
ac.Spec.AuthParameter.KeyAuth)
                if err != nil {
                        return nil, fmt.Errorf("invalid key auth config: %s", 
err)
                }
                plugins["key-auth"] = cfg
        } else if ac.Spec.AuthParameter.BasicAuth != nil {
-               cfg, err := t.translateConsumerBasicAuthPlugin(ac.Namespace, 
ac.Spec.AuthParameter.BasicAuth)
+               cfg, err := 
t.translateConsumerBasicAuthPluginV2beta3(ac.Namespace, 
ac.Spec.AuthParameter.BasicAuth)
                if err != nil {
                        return nil, fmt.Errorf("invalid basic auth config: %s", 
err)
                }
                plugins["basic-auth"] = cfg
        } else if ac.Spec.AuthParameter.JwtAuth != nil {
-               cfg, err := t.translateConsumerJwtAuthPlugin(ac.Namespace, 
ac.Spec.AuthParameter.JwtAuth)
+               cfg, err := 
t.translateConsumerJwtAuthPluginV2beta3(ac.Namespace, 
ac.Spec.AuthParameter.JwtAuth)
                if err != nil {
                        return nil, fmt.Errorf("invalid jwt auth config: %s", 
err)
                }
                plugins["jwt-auth"] = cfg
        } else if ac.Spec.AuthParameter.WolfRBAC != nil {
-               cfg, err := t.translateConsumerWolfRBACPlugin(ac.Namespace, 
ac.Spec.AuthParameter.WolfRBAC)
+               cfg, err := 
t.translateConsumerWolfRBACPluginV2beta3(ac.Namespace, 
ac.Spec.AuthParameter.WolfRBAC)
+               if err != nil {
+                       return nil, fmt.Errorf("invalid wolf rbac config: %s", 
err)
+               }
+               plugins["wolf-rbac"] = cfg
+       }
+
+       consumer := apisixv1.NewDefaultConsumer()
+       consumer.Username = apisixv1.ComposeConsumerName(ac.Namespace, ac.Name)
+       consumer.Plugins = plugins
+       return consumer, nil
+}
+
+func (t *translator) TranslateApisixConsumerV2(ac *configv2.ApisixConsumer) 
(*apisixv1.Consumer, error) {
+       // As the CRD schema ensures that only one authN can be configured,
+       // so here the order is no matter.
+
+       plugins := make(apisixv1.Plugins)
+       if ac.Spec.AuthParameter.KeyAuth != nil {
+               cfg, err := t.translateConsumerKeyAuthPluginV2(ac.Namespace, 
ac.Spec.AuthParameter.KeyAuth)
+               if err != nil {
+                       return nil, fmt.Errorf("invalid key auth config: %s", 
err)
+               }
+               plugins["key-auth"] = cfg
+       } else if ac.Spec.AuthParameter.BasicAuth != nil {
+               cfg, err := t.translateConsumerBasicAuthPluginV2(ac.Namespace, 
ac.Spec.AuthParameter.BasicAuth)
+               if err != nil {
+                       return nil, fmt.Errorf("invalid basic auth config: %s", 
err)
+               }
+               plugins["basic-auth"] = cfg
+       } else if ac.Spec.AuthParameter.JwtAuth != nil {
+               cfg, err := t.translateConsumerJwtAuthPluginV2(ac.Namespace, 
ac.Spec.AuthParameter.JwtAuth)
+               if err != nil {
+                       return nil, fmt.Errorf("invalid jwt auth config: %s", 
err)
+               }
+               plugins["jwt-auth"] = cfg
+       } else if ac.Spec.AuthParameter.WolfRBAC != nil {
+               cfg, err := t.translateConsumerWolfRBACPluginV2(ac.Namespace, 
ac.Spec.AuthParameter.WolfRBAC)
                if err != nil {
                        return nil, fmt.Errorf("invalid wolf rbac config: %s", 
err)
                }
diff --git a/pkg/kube/translation/apisix_consumer_test.go 
b/pkg/kube/translation/apisix_consumer_test.go
index 775e2a3a..a875c8a6 100644
--- a/pkg/kube/translation/apisix_consumer_test.go
+++ b/pkg/kube/translation/apisix_consumer_test.go
@@ -20,11 +20,12 @@ import (
        "github.com/stretchr/testify/assert"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+       configv2 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2"
        configv2beta3 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2beta3"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
 
-func TestTranslateApisixConsumer(t *testing.T) {
+func TestTranslateApisixConsumerV2beta3(t *testing.T) {
        ac := &configv2beta3.ApisixConsumer{
                ObjectMeta: metav1.ObjectMeta{
                        Name:      "jack",
@@ -41,7 +42,7 @@ func TestTranslateApisixConsumer(t *testing.T) {
                        },
                },
        }
-       consumer, err := (&translator{}).TranslateApisixConsumer(ac)
+       consumer, err := (&translator{}).TranslateApisixConsumerV2beta3(ac)
        assert.Nil(t, err)
        assert.Len(t, consumer.Plugins, 1)
        cfg := 
consumer.Plugins["basic-auth"].(*apisixv1.BasicAuthConsumerConfig)
@@ -63,7 +64,7 @@ func TestTranslateApisixConsumer(t *testing.T) {
                        },
                },
        }
-       consumer, err = (&translator{}).TranslateApisixConsumer(ac)
+       consumer, err = (&translator{}).TranslateApisixConsumerV2beta3(ac)
        assert.Nil(t, err)
        assert.Len(t, consumer.Plugins, 1)
        cfg2 := consumer.Plugins["key-auth"].(*apisixv1.KeyAuthConsumerConfig)
@@ -90,7 +91,7 @@ func TestTranslateApisixConsumer(t *testing.T) {
                        },
                },
        }
-       consumer, err = (&translator{}).TranslateApisixConsumer(ac)
+       consumer, err = (&translator{}).TranslateApisixConsumerV2beta3(ac)
        assert.Nil(t, err)
        assert.Len(t, consumer.Plugins, 1)
        cfg3 := consumer.Plugins["jwt-auth"].(*apisixv1.JwtAuthConsumerConfig)
@@ -118,7 +119,112 @@ func TestTranslateApisixConsumer(t *testing.T) {
                        },
                },
        }
-       consumer, err = (&translator{}).TranslateApisixConsumer(ac)
+       consumer, err = (&translator{}).TranslateApisixConsumerV2beta3(ac)
+       assert.Nil(t, err)
+       assert.Len(t, consumer.Plugins, 1)
+       cfg4 := consumer.Plugins["wolf-rbac"].(*apisixv1.WolfRBACConsumerConfig)
+       assert.Equal(t, "https://httpbin.org";, cfg4.Server)
+       assert.Equal(t, "test01", cfg4.Appid)
+
+       // No test test cases for secret references as we already test them
+       // in plugin_test.go.
+}
+
+func TestTranslateApisixConsumerV2(t *testing.T) {
+       ac := &configv2.ApisixConsumer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "jack",
+                       Namespace: "qa",
+               },
+               Spec: configv2.ApisixConsumerSpec{
+                       AuthParameter: configv2.ApisixConsumerAuthParameter{
+                               BasicAuth: &configv2.ApisixConsumerBasicAuth{
+                                       Value: 
&configv2.ApisixConsumerBasicAuthValue{
+                                               Username: "jack",
+                                               Password: "jacknice",
+                                       },
+                               },
+                       },
+               },
+       }
+       consumer, err := (&translator{}).TranslateApisixConsumerV2(ac)
+       assert.Nil(t, err)
+       assert.Len(t, consumer.Plugins, 1)
+       cfg := 
consumer.Plugins["basic-auth"].(*apisixv1.BasicAuthConsumerConfig)
+       assert.Equal(t, "jack", cfg.Username)
+       assert.Equal(t, "jacknice", cfg.Password)
+
+       ac = &configv2.ApisixConsumer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "jack",
+                       Namespace: "qa",
+               },
+               Spec: configv2.ApisixConsumerSpec{
+                       AuthParameter: configv2.ApisixConsumerAuthParameter{
+                               KeyAuth: &configv2.ApisixConsumerKeyAuth{
+                                       Value: 
&configv2.ApisixConsumerKeyAuthValue{
+                                               Key: "qwerty",
+                                       },
+                               },
+                       },
+               },
+       }
+       consumer, err = (&translator{}).TranslateApisixConsumerV2(ac)
+       assert.Nil(t, err)
+       assert.Len(t, consumer.Plugins, 1)
+       cfg2 := consumer.Plugins["key-auth"].(*apisixv1.KeyAuthConsumerConfig)
+       assert.Equal(t, "qwerty", cfg2.Key)
+
+       ac = &configv2.ApisixConsumer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "jack",
+                       Namespace: "qa",
+               },
+               Spec: configv2.ApisixConsumerSpec{
+                       AuthParameter: configv2.ApisixConsumerAuthParameter{
+                               JwtAuth: &configv2.ApisixConsumerJwtAuth{
+                                       Value: 
&configv2.ApisixConsumerJwtAuthValue{
+                                               Key:          "foo",
+                                               Secret:       "123",
+                                               PublicKey:    "public",
+                                               PrivateKey:   "private",
+                                               Algorithm:    "HS256",
+                                               Exp:          int64(1000),
+                                               Base64Secret: true,
+                                       },
+                               },
+                       },
+               },
+       }
+       consumer, err = (&translator{}).TranslateApisixConsumerV2(ac)
+       assert.Nil(t, err)
+       assert.Len(t, consumer.Plugins, 1)
+       cfg3 := consumer.Plugins["jwt-auth"].(*apisixv1.JwtAuthConsumerConfig)
+       assert.Equal(t, "foo", cfg3.Key)
+       assert.Equal(t, "123", cfg3.Secret)
+       assert.Equal(t, "public", cfg3.PublicKey)
+       assert.Equal(t, "private", cfg3.PrivateKey)
+       assert.Equal(t, "HS256", cfg3.Algorithm)
+       assert.Equal(t, int64(1000), cfg3.Exp)
+       assert.Equal(t, true, cfg3.Base64Secret)
+
+       ac = &configv2.ApisixConsumer{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "jack",
+                       Namespace: "qa",
+               },
+               Spec: configv2.ApisixConsumerSpec{
+                       AuthParameter: configv2.ApisixConsumerAuthParameter{
+                               WolfRBAC: &configv2.ApisixConsumerWolfRBAC{
+                                       Value: 
&configv2.ApisixConsumerWolfRBACValue{
+                                               Server: "https://httpbin.org";,
+                                               Appid:  "test01",
+                                       },
+                               },
+                       },
+               },
+       }
+       consumer, err = (&translator{}).TranslateApisixConsumerV2(ac)
        assert.Nil(t, err)
        assert.Len(t, consumer.Plugins, 1)
        cfg4 := consumer.Plugins["wolf-rbac"].(*apisixv1.WolfRBACConsumerConfig)
diff --git a/pkg/kube/translation/plugin.go b/pkg/kube/translation/plugin.go
index c2a9b109..5b532932 100644
--- a/pkg/kube/translation/plugin.go
+++ b/pkg/kube/translation/plugin.go
@@ -73,7 +73,7 @@ func (t *translator) translateTrafficSplitPlugin(ctx 
*TranslateContext, ns strin
        return tsCfg, nil
 }
 
-func (t *translator) translateConsumerKeyAuthPlugin(consumerNamespace string, 
cfg *configv2beta3.ApisixConsumerKeyAuth) (*apisixv1.KeyAuthConsumerConfig, 
error) {
+func (t *translator) translateConsumerKeyAuthPluginV2beta3(consumerNamespace 
string, cfg *configv2beta3.ApisixConsumerKeyAuth) 
(*apisixv1.KeyAuthConsumerConfig, error) {
        if cfg.Value != nil {
                return &apisixv1.KeyAuthConsumerConfig{Key: cfg.Value.Key}, nil
        }
@@ -89,7 +89,7 @@ func (t *translator) 
translateConsumerKeyAuthPlugin(consumerNamespace string, cf
        return &apisixv1.KeyAuthConsumerConfig{Key: string(raw)}, nil
 }
 
-func (t *translator) translateConsumerBasicAuthPlugin(consumerNamespace 
string, cfg *configv2beta3.ApisixConsumerBasicAuth) 
(*apisixv1.BasicAuthConsumerConfig, error) {
+func (t *translator) translateConsumerBasicAuthPluginV2beta3(consumerNamespace 
string, cfg *configv2beta3.ApisixConsumerBasicAuth) 
(*apisixv1.BasicAuthConsumerConfig, error) {
        if cfg.Value != nil {
                return &apisixv1.BasicAuthConsumerConfig{
                        Username: cfg.Value.Username,
@@ -115,7 +115,49 @@ func (t *translator) 
translateConsumerBasicAuthPlugin(consumerNamespace string,
        }, nil
 }
 
-func (t *translator) translateConsumerWolfRBACPlugin(consumerNamespace string, 
cfg *configv2beta3.ApisixConsumerWolfRBAC) (*apisixv1.WolfRBACConsumerConfig, 
error) {
+func (t *translator) translateConsumerKeyAuthPluginV2(consumerNamespace 
string, cfg *configv2.ApisixConsumerKeyAuth) (*apisixv1.KeyAuthConsumerConfig, 
error) {
+       if cfg.Value != nil {
+               return &apisixv1.KeyAuthConsumerConfig{Key: cfg.Value.Key}, nil
+       }
+
+       sec, err := 
t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
+       if err != nil {
+               return nil, err
+       }
+       raw, ok := sec.Data["key"]
+       if !ok || len(raw) == 0 {
+               return nil, _errKeyNotFoundOrInvalid
+       }
+       return &apisixv1.KeyAuthConsumerConfig{Key: string(raw)}, nil
+}
+
+func (t *translator) translateConsumerBasicAuthPluginV2(consumerNamespace 
string, cfg *configv2.ApisixConsumerBasicAuth) 
(*apisixv1.BasicAuthConsumerConfig, error) {
+       if cfg.Value != nil {
+               return &apisixv1.BasicAuthConsumerConfig{
+                       Username: cfg.Value.Username,
+                       Password: cfg.Value.Password,
+               }, nil
+       }
+
+       sec, err := 
t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
+       if err != nil {
+               return nil, err
+       }
+       raw1, ok := sec.Data["username"]
+       if !ok || len(raw1) == 0 {
+               return nil, _errUsernameNotFoundOrInvalid
+       }
+       raw2, ok := sec.Data["password"]
+       if !ok || len(raw2) == 0 {
+               return nil, _errPasswordNotFoundOrInvalid
+       }
+       return &apisixv1.BasicAuthConsumerConfig{
+               Username: string(raw1),
+               Password: string(raw2),
+       }, nil
+}
+
+func (t *translator) translateConsumerWolfRBACPluginV2beta3(consumerNamespace 
string, cfg *configv2beta3.ApisixConsumerWolfRBAC) 
(*apisixv1.WolfRBACConsumerConfig, error) {
        if cfg.Value != nil {
                return &apisixv1.WolfRBACConsumerConfig{
                        Server:       cfg.Value.Server,
@@ -137,7 +179,80 @@ func (t *translator) 
translateConsumerWolfRBACPlugin(consumerNamespace string, c
        }, nil
 }
 
-func (t *translator) translateConsumerJwtAuthPlugin(consumerNamespace string, 
cfg *configv2beta3.ApisixConsumerJwtAuth) (*apisixv1.JwtAuthConsumerConfig, 
error) {
+func (t *translator) translateConsumerWolfRBACPluginV2(consumerNamespace 
string, cfg *configv2.ApisixConsumerWolfRBAC) 
(*apisixv1.WolfRBACConsumerConfig, error) {
+       if cfg.Value != nil {
+               return &apisixv1.WolfRBACConsumerConfig{
+                       Server:       cfg.Value.Server,
+                       Appid:        cfg.Value.Appid,
+                       HeaderPrefix: cfg.Value.HeaderPrefix,
+               }, nil
+       }
+       sec, err := 
t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
+       if err != nil {
+               return nil, err
+       }
+       raw1 := sec.Data["server"]
+       raw2 := sec.Data["appid"]
+       raw3 := sec.Data["header_prefix"]
+       return &apisixv1.WolfRBACConsumerConfig{
+               Server:       string(raw1),
+               Appid:        string(raw2),
+               HeaderPrefix: string(raw3),
+       }, nil
+}
+
+func (t *translator) translateConsumerJwtAuthPluginV2beta3(consumerNamespace 
string, cfg *configv2beta3.ApisixConsumerJwtAuth) 
(*apisixv1.JwtAuthConsumerConfig, error) {
+       if cfg.Value != nil {
+               // The field exp must be a positive integer, default value 
86400.
+               if cfg.Value.Exp < 1 {
+                       cfg.Value.Exp = _jwtAuthExpDefaultValue
+               }
+               return &apisixv1.JwtAuthConsumerConfig{
+                       Key:          cfg.Value.Key,
+                       Secret:       cfg.Value.Secret,
+                       PublicKey:    cfg.Value.PublicKey,
+                       PrivateKey:   cfg.Value.PrivateKey,
+                       Algorithm:    cfg.Value.Algorithm,
+                       Exp:          cfg.Value.Exp,
+                       Base64Secret: cfg.Value.Base64Secret,
+               }, nil
+       }
+
+       sec, err := 
t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
+       if err != nil {
+               return nil, err
+       }
+       keyRaw, ok := sec.Data["key"]
+       if !ok || len(keyRaw) == 0 {
+               return nil, _errKeyNotFoundOrInvalid
+       }
+       base64SecretRaw := sec.Data["base64_secret"]
+       var base64Secret bool
+       if string(base64SecretRaw) == "true" {
+               base64Secret = true
+       }
+       expRaw := sec.Data["exp"]
+       exp, _ := strconv.ParseInt(string(expRaw), 10, 64)
+       // The field exp must be a positive integer, default value 86400.
+       if exp < 1 {
+               exp = _jwtAuthExpDefaultValue
+       }
+       secretRaw := sec.Data["secret"]
+       publicKeyRaw := sec.Data["public_key"]
+       privateKeyRaw := sec.Data["private_key"]
+       algorithmRaw := sec.Data["algorithm"]
+       return &apisixv1.JwtAuthConsumerConfig{
+               Key:          string(keyRaw),
+               Secret:       string(secretRaw),
+               PublicKey:    string(publicKeyRaw),
+               PrivateKey:   string(privateKeyRaw),
+               Algorithm:    string(algorithmRaw),
+               Exp:          exp,
+               Base64Secret: base64Secret,
+       }, nil
+}
+
+func (t *translator) translateConsumerJwtAuthPluginV2(consumerNamespace 
string, cfg *configv2.ApisixConsumerJwtAuth) (*apisixv1.JwtAuthConsumerConfig, 
error) {
        if cfg.Value != nil {
                // The field exp must be a positive integer, default value 
86400.
                if cfg.Value.Exp < 1 {
diff --git a/pkg/kube/translation/plugin_test.go 
b/pkg/kube/translation/plugin_test.go
index a6cad20f..94cbc9ee 100644
--- a/pkg/kube/translation/plugin_test.go
+++ b/pkg/kube/translation/plugin_test.go
@@ -539,7 +539,7 @@ func TestTranslateConsumerKeyAuthPluginWithInPlaceValue(t 
*testing.T) {
        keyAuth := &configv2beta3.ApisixConsumerKeyAuth{
                Value: &configv2beta3.ApisixConsumerKeyAuthValue{Key: "abc"},
        }
-       cfg, err := (&translator{}).translateConsumerKeyAuthPlugin("default", 
keyAuth)
+       cfg, err := 
(&translator{}).translateConsumerKeyAuthPluginV2beta3("default", keyAuth)
        assert.Nil(t, err)
        assert.Equal(t, "abc", cfg.Key)
 }
@@ -582,11 +582,11 @@ func TestTranslateConsumerKeyAuthWithSecretRef(t 
*testing.T) {
        keyAuth := &configv2beta3.ApisixConsumerKeyAuth{
                SecretRef: &corev1.LocalObjectReference{Name: "abc-key-auth"},
        }
-       cfg, err := tr.translateConsumerKeyAuthPlugin("default", keyAuth)
+       cfg, err := tr.translateConsumerKeyAuthPluginV2beta3("default", keyAuth)
        assert.Nil(t, err)
        assert.Equal(t, "abc", cfg.Key)
 
-       cfg, err = tr.translateConsumerKeyAuthPlugin("default2", keyAuth)
+       cfg, err = tr.translateConsumerKeyAuthPluginV2beta3("default2", keyAuth)
        assert.Nil(t, cfg)
        assert.NotNil(t, err)
        assert.Contains(t, err.Error(), "not found")
@@ -596,7 +596,7 @@ func TestTranslateConsumerKeyAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerKeyAuthPlugin("default", keyAuth)
+       cfg, err = tr.translateConsumerKeyAuthPluginV2beta3("default", keyAuth)
        assert.Nil(t, cfg)
        assert.Equal(t, _errKeyNotFoundOrInvalid, err)
 
@@ -611,7 +611,7 @@ func TestTranslateConsumerBasicAuthPluginWithInPlaceValue(t 
*testing.T) {
                        Password: "jacknice",
                },
        }
-       cfg, err := (&translator{}).translateConsumerBasicAuthPlugin("default", 
basicAuth)
+       cfg, err := 
(&translator{}).translateConsumerBasicAuthPluginV2beta3("default", basicAuth)
        assert.Nil(t, err)
        assert.Equal(t, "jack", cfg.Username)
        assert.Equal(t, "jacknice", cfg.Password)
@@ -656,12 +656,12 @@ func TestTranslateConsumerBasicAuthWithSecretRef(t 
*testing.T) {
        basicAuth := &configv2beta3.ApisixConsumerBasicAuth{
                SecretRef: &corev1.LocalObjectReference{Name: 
"jack-basic-auth"},
        }
-       cfg, err := tr.translateConsumerBasicAuthPlugin("default", basicAuth)
+       cfg, err := tr.translateConsumerBasicAuthPluginV2beta3("default", 
basicAuth)
        assert.Nil(t, err)
        assert.Equal(t, "jack", cfg.Username)
        assert.Equal(t, "jacknice", cfg.Password)
 
-       cfg, err = tr.translateConsumerBasicAuthPlugin("default2", basicAuth)
+       cfg, err = tr.translateConsumerBasicAuthPluginV2beta3("default2", 
basicAuth)
        assert.Nil(t, cfg)
        assert.NotNil(t, err)
        assert.Contains(t, err.Error(), "not found")
@@ -671,7 +671,7 @@ func TestTranslateConsumerBasicAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerBasicAuthPlugin("default", basicAuth)
+       cfg, err = tr.translateConsumerBasicAuthPluginV2beta3("default", 
basicAuth)
        assert.Nil(t, cfg)
        assert.Equal(t, _errPasswordNotFoundOrInvalid, err)
 
@@ -680,7 +680,7 @@ func TestTranslateConsumerBasicAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerBasicAuthPlugin("default", basicAuth)
+       cfg, err = tr.translateConsumerBasicAuthPluginV2beta3("default", 
basicAuth)
        assert.Nil(t, cfg)
        assert.Equal(t, _errUsernameNotFoundOrInvalid, err)
 
@@ -700,7 +700,7 @@ func TestTranslateConsumerJwtAuthPluginWithInPlaceValue(t 
*testing.T) {
                        Base64Secret: true,
                },
        }
-       cfg, err := (&translator{}).translateConsumerJwtAuthPlugin("default", 
jwtAuth)
+       cfg, err := 
(&translator{}).translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
        assert.Equal(t, "foo", cfg.Key)
        assert.Equal(t, "foo-secret", cfg.Secret)
@@ -711,7 +711,7 @@ func TestTranslateConsumerJwtAuthPluginWithInPlaceValue(t 
*testing.T) {
        assert.Equal(t, true, cfg.Base64Secret)
 
        jwtAuth.Value.Exp = int64(-1)
-       cfg, err = (&translator{}).translateConsumerJwtAuthPlugin("default", 
jwtAuth)
+       cfg, err = 
(&translator{}).translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
        assert.Equal(t, int64(_jwtAuthExpDefaultValue), cfg.Exp)
 
@@ -720,7 +720,7 @@ func TestTranslateConsumerJwtAuthPluginWithInPlaceValue(t 
*testing.T) {
                        Key: "foo2",
                },
        }
-       cfg, err = (&translator{}).translateConsumerJwtAuthPlugin("default", 
jwtAuth2)
+       cfg, err = 
(&translator{}).translateConsumerJwtAuthPluginV2beta3("default", jwtAuth2)
        assert.Nil(t, err)
        assert.Equal(t, "foo2", cfg.Key)
 }
@@ -769,7 +769,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        jwtAuth := &configv2beta3.ApisixConsumerJwtAuth{
                SecretRef: &corev1.LocalObjectReference{Name: "jack-jwt-auth"},
        }
-       cfg, err := tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err := tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
        assert.Equal(t, "foo", cfg.Key)
        assert.Equal(t, "foo-secret", cfg.Secret)
@@ -779,7 +779,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Equal(t, int64(1000), cfg.Exp)
        assert.Equal(t, true, cfg.Base64Secret)
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default2", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default2", jwtAuth)
        assert.Nil(t, cfg)
        assert.NotNil(t, err)
        assert.Contains(t, err.Error(), "not found")
@@ -789,7 +789,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "public")
@@ -797,7 +797,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "private")
@@ -805,7 +805,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "algorithm")
@@ -813,7 +813,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "exp")
@@ -821,7 +821,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "base64_secret")
@@ -829,7 +829,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, err)
 
        delete(sec.Data, "key")
@@ -837,7 +837,7 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerJwtAuthPlugin("default", jwtAuth)
+       cfg, err = tr.translateConsumerJwtAuthPluginV2beta3("default", jwtAuth)
        assert.Nil(t, cfg)
        assert.Equal(t, _errKeyNotFoundOrInvalid, err)
 
@@ -852,7 +852,7 @@ func TestTranslateConsumerWolfRBACPluginWithInPlaceValue(t 
*testing.T) {
                        Appid:  "test-app",
                },
        }
-       cfg, err := (&translator{}).translateConsumerWolfRBACPlugin("default", 
wolfRBAC)
+       cfg, err := 
(&translator{}).translateConsumerWolfRBACPluginV2beta3("default", wolfRBAC)
        assert.Nil(t, err)
        assert.Equal(t, "https://httpbin.org";, cfg.Server)
        assert.Equal(t, "test-app", cfg.Appid)
@@ -898,13 +898,13 @@ func TestTranslateConsumerWolfRBACWithSecretRef(t 
*testing.T) {
        wolfRBAC := &configv2beta3.ApisixConsumerWolfRBAC{
                SecretRef: &corev1.LocalObjectReference{Name: "jack-wolf-rbac"},
        }
-       cfg, err := tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
+       cfg, err := tr.translateConsumerWolfRBACPluginV2beta3("default", 
wolfRBAC)
        assert.Nil(t, err)
        assert.Equal(t, "http://127.0.0.1:12180";, cfg.Server)
        assert.Equal(t, "test-app", cfg.Appid)
        assert.Equal(t, "X-", cfg.HeaderPrefix)
 
-       cfg, err = tr.translateConsumerWolfRBACPlugin("default2", wolfRBAC)
+       cfg, err = tr.translateConsumerWolfRBACPluginV2beta3("default2", 
wolfRBAC)
        assert.Nil(t, cfg)
        assert.NotNil(t, err)
        assert.Contains(t, err.Error(), "not found")
@@ -914,7 +914,7 @@ func TestTranslateConsumerWolfRBACWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
+       cfg, err = tr.translateConsumerWolfRBACPluginV2beta3("default", 
wolfRBAC)
        assert.Nil(t, err)
 
        delete(sec.Data, "appid")
@@ -922,7 +922,7 @@ func TestTranslateConsumerWolfRBACWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
+       cfg, err = tr.translateConsumerWolfRBACPluginV2beta3("default", 
wolfRBAC)
        assert.Nil(t, err)
 
        delete(sec.Data, "header_prefix")
@@ -930,7 +930,7 @@ func TestTranslateConsumerWolfRBACWithSecretRef(t 
*testing.T) {
        assert.Nil(t, err)
        <-processCh
 
-       cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
+       cfg, err = tr.translateConsumerWolfRBACPluginV2beta3("default", 
wolfRBAC)
        assert.Nil(t, err)
 
        close(processCh)
diff --git a/pkg/kube/translation/translator.go 
b/pkg/kube/translation/translator.go
index 2acc5b4c..d0291abe 100644
--- a/pkg/kube/translation/translator.go
+++ b/pkg/kube/translation/translator.go
@@ -95,8 +95,11 @@ type Translator interface {
        TranslateClusterConfigV2(*configv2.ApisixClusterConfig) 
(*apisixv1.GlobalRule, error)
        // TranslateApisixConsumer translates the configv2beta3.APisixConsumer 
object into the APISIX Consumer
        // resource.
-       TranslateApisixConsumer(*configv2beta3.ApisixConsumer) 
(*apisixv1.Consumer, error)
-       // TranslatePluginConfigV2beta3 translates the 
configv2beta3.ApisixPluginConfig object into several PluginConfig
+       TranslateApisixConsumerV2beta3(*configv2beta3.ApisixConsumer) 
(*apisixv1.Consumer, error)
+       // TranslateApisixConsumerV2 translates the 
configv2beta3.APisixConsumer object into the APISIX Consumer
+       // resource.
+       TranslateApisixConsumerV2(ac *configv2.ApisixConsumer) 
(*apisixv1.Consumer, error)
+       // TranslatePluginConfigV2beta3 translates the 
configv2.ApisixPluginConfig object into several PluginConfig
        // resources.
        TranslatePluginConfigV2beta3(*configv2beta3.ApisixPluginConfig) 
(*TranslateContext, error)
        // TranslatePluginConfigV2beta3NotStrictly translates the 
configv2beta3.ApisixPluginConfig object into several PluginConfig

Reply via email to