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

tokers 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 bc71e3e  chore: add apisixconsumer data structures (#462)
bc71e3e is described below

commit bc71e3e25a8514548fddbf900318457ded3e3076
Author: Alex Zhang <[email protected]>
AuthorDate: Mon May 24 17:10:27 2021 +0800

    chore: add apisixconsumer data structures (#462)
---
 pkg/kube/apisix/apis/config/v2alpha1/types.go      |  56 ++++++
 .../apis/config/v2alpha1/zz_generated.deepcopy.go  | 195 ++++++++++++++++++++-
 .../typed/config/v2alpha1/apisixconsumer.go        | 195 +++++++++++++++++++++
 .../typed/config/v2alpha1/config_client.go         |   5 +
 .../config/v2alpha1/fake/fake_apisixconsumer.go    | 142 +++++++++++++++
 .../config/v2alpha1/fake/fake_config_client.go     |   4 +
 .../typed/config/v2alpha1/generated_expansion.go   |   2 +
 .../config/v2alpha1/apisixconsumer.go              |  90 ++++++++++
 .../externalversions/config/v2alpha1/interface.go  |   7 +
 .../client/informers/externalversions/generic.go   |   2 +
 .../listers/config/v2alpha1/apisixconsumer.go      |  99 +++++++++++
 .../listers/config/v2alpha1/expansion_generated.go |   8 +
 samples/deploy/crd/v1beta1/ApisixConsumer.yaml     | 100 +++++++++++
 samples/deploy/rbac/apisix_view_clusterrole.yaml   |   1 +
 test/e2e/scaffold/ingress.go                       |   1 +
 15 files changed, 904 insertions(+), 3 deletions(-)

diff --git a/pkg/kube/apisix/apis/config/v2alpha1/types.go 
b/pkg/kube/apisix/apis/config/v2alpha1/types.go
index c96448d..0e984f8 100644
--- a/pkg/kube/apisix/apis/config/v2alpha1/types.go
+++ b/pkg/kube/apisix/apis/config/v2alpha1/types.go
@@ -17,6 +17,7 @@ package v2alpha1
 import (
        "encoding/json"
 
+       corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/util/intstr"
 )
@@ -309,3 +310,58 @@ type ApisixClusterConfigList struct {
 
        Items []ApisixClusterConfig `json:"items" yaml:"items"`
 }
+
+// +genclient
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +kubebuilder:subresource:status
+
+// ApisixConsumer is the Schema for the ApisixConsumer resource.
+// An ApisixConsumer is used to identify a consumer.
+type ApisixConsumer struct {
+       metav1.TypeMeta   `json:",inline" yaml:",inline"`
+       metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
+       Spec              ApisixConsumerSpec `json:"spec,omitempty" 
yaml:"spec,omitempty"`
+       Status            ApisixStatus       `json:"status,omitempty" 
yaml:"status,omitempty"`
+}
+
+// ApisixConsumerSpec defines the desired state of ApisixConsumer.
+type ApisixConsumerSpec struct {
+       AuthParameter ApisixConsumerAuthParameter `json:"authParameter" 
yaml:"authParameter"`
+}
+
+type ApisixConsumerAuthParameter struct {
+       BasicAuth *ApisixConsumerBasicAuth `json:"basicAuth,omitempty" 
yaml:"basicAuth"`
+       KeyAuth   *ApisixConsumerKeyAuth   `json:"keyAuth,omitempty" 
yaml:"keyAuth"`
+}
+
+// ApisixConsumerBasicAuth defines the configuration for basic auth.
+type ApisixConsumerBasicAuth struct {
+       SecretRef *corev1.LocalObjectReference  `json:"secretRef,omitempty" 
yaml:"secretRef,omitempty"`
+       Value     *ApisixConsumerBasicAuthValue `json:"value,omitempty" 
yaml:"value,omitempty"`
+}
+
+// ApisixConsumerBasicAuthValue defines the in-place username and password 
configuration for basic auth.
+type ApisixConsumerBasicAuthValue struct {
+       Username string `json:"username" yaml:"username"`
+       Password string `json:"password" yaml:"username"`
+}
+
+// ApisixConsumerKeyAuth defines the configuration for the key auth.
+type ApisixConsumerKeyAuth struct {
+       SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty" 
yaml:"secretRef,omitempty"`
+       Value     *ApisixConsumerKeyAuthValue  `json:"value,omitempty" 
yaml:"value,omitempty"`
+}
+
+// ApisixConsumerKeyAuthValue defines the in-place configuration for basic 
auth.
+type ApisixConsumerKeyAuthValue struct {
+       Key string `json:"key" yaml:"key"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ApisixConsumerList contains a list of ApisixConsumer.
+type ApisixConsumerList struct {
+       metav1.TypeMeta `json:",inline" yaml:",inline"`
+       metav1.ListMeta `json:"metadata" yaml:"metadata"`
+       Items           []ApisixRoute `json:"items,omitempty" 
yaml:"items,omitempty"`
+}
diff --git a/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go 
b/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
index c11e22c..fdb67b3 100644
--- a/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
+++ b/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
@@ -21,7 +21,8 @@ limitations under the License.
 package v2alpha1
 
 import (
-       v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       v1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        runtime "k8s.io/apimachinery/pkg/runtime"
 )
 
@@ -178,6 +179,194 @@ func (in *ApisixClusterSkywalkingConfig) DeepCopy() 
*ApisixClusterSkywalkingConf
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumer) DeepCopyInto(out *ApisixConsumer) {
+       *out = *in
+       out.TypeMeta = in.TypeMeta
+       in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+       in.Spec.DeepCopyInto(&out.Spec)
+       in.Status.DeepCopyInto(&out.Status)
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumer.
+func (in *ApisixConsumer) DeepCopy() *ApisixConsumer {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumer)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, 
creating a new runtime.Object.
+func (in *ApisixConsumer) DeepCopyObject() runtime.Object {
+       if c := in.DeepCopy(); c != nil {
+               return c
+       }
+       return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerAuthParameter) DeepCopyInto(out 
*ApisixConsumerAuthParameter) {
+       *out = *in
+       if in.BasicAuth != nil {
+               in, out := &in.BasicAuth, &out.BasicAuth
+               *out = new(ApisixConsumerBasicAuth)
+               (*in).DeepCopyInto(*out)
+       }
+       if in.KeyAuth != nil {
+               in, out := &in.KeyAuth, &out.KeyAuth
+               *out = new(ApisixConsumerKeyAuth)
+               (*in).DeepCopyInto(*out)
+       }
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerAuthParameter.
+func (in *ApisixConsumerAuthParameter) DeepCopy() *ApisixConsumerAuthParameter 
{
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerAuthParameter)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerBasicAuth) DeepCopyInto(out *ApisixConsumerBasicAuth) {
+       *out = *in
+       if in.SecretRef != nil {
+               in, out := &in.SecretRef, &out.SecretRef
+               *out = new(v1.LocalObjectReference)
+               **out = **in
+       }
+       if in.Value != nil {
+               in, out := &in.Value, &out.Value
+               *out = new(ApisixConsumerBasicAuthValue)
+               **out = **in
+       }
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerBasicAuth.
+func (in *ApisixConsumerBasicAuth) DeepCopy() *ApisixConsumerBasicAuth {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerBasicAuth)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerBasicAuthValue) DeepCopyInto(out 
*ApisixConsumerBasicAuthValue) {
+       *out = *in
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerBasicAuthValue.
+func (in *ApisixConsumerBasicAuthValue) DeepCopy() 
*ApisixConsumerBasicAuthValue {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerBasicAuthValue)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerKeyAuth) DeepCopyInto(out *ApisixConsumerKeyAuth) {
+       *out = *in
+       if in.SecretRef != nil {
+               in, out := &in.SecretRef, &out.SecretRef
+               *out = new(v1.LocalObjectReference)
+               **out = **in
+       }
+       if in.Value != nil {
+               in, out := &in.Value, &out.Value
+               *out = new(ApisixConsumerKeyAuthValue)
+               **out = **in
+       }
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerKeyAuth.
+func (in *ApisixConsumerKeyAuth) DeepCopy() *ApisixConsumerKeyAuth {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerKeyAuth)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerKeyAuthValue) DeepCopyInto(out 
*ApisixConsumerKeyAuthValue) {
+       *out = *in
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerKeyAuthValue.
+func (in *ApisixConsumerKeyAuthValue) DeepCopy() *ApisixConsumerKeyAuthValue {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerKeyAuthValue)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerList) DeepCopyInto(out *ApisixConsumerList) {
+       *out = *in
+       out.TypeMeta = in.TypeMeta
+       in.ListMeta.DeepCopyInto(&out.ListMeta)
+       if in.Items != nil {
+               in, out := &in.Items, &out.Items
+               *out = make([]ApisixRoute, len(*in))
+               for i := range *in {
+                       (*in)[i].DeepCopyInto(&(*out)[i])
+               }
+       }
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerList.
+func (in *ApisixConsumerList) DeepCopy() *ApisixConsumerList {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerList)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, 
creating a new runtime.Object.
+func (in *ApisixConsumerList) DeepCopyObject() runtime.Object {
+       if c := in.DeepCopy(); c != nil {
+               return c
+       }
+       return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ApisixConsumerSpec) DeepCopyInto(out *ApisixConsumerSpec) {
+       *out = *in
+       in.AuthParameter.DeepCopyInto(&out.AuthParameter)
+       return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ApisixConsumerSpec.
+func (in *ApisixConsumerSpec) DeepCopy() *ApisixConsumerSpec {
+       if in == nil {
+               return nil
+       }
+       out := new(ApisixConsumerSpec)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *ApisixRoute) DeepCopyInto(out *ApisixRoute) {
        *out = *in
        out.TypeMeta = in.TypeMeta
@@ -509,10 +698,10 @@ func (in *ApisixStatus) DeepCopyInto(out *ApisixStatus) {
        *out = *in
        if in.Conditions != nil {
                in, out := &in.Conditions, &out.Conditions
-               *out = new([]v1.Condition)
+               *out = new([]metav1.Condition)
                if **in != nil {
                        in, out := *in, *out
-                       *out = make([]v1.Condition, len(*in))
+                       *out = make([]metav1.Condition, len(*in))
                        for i := range *in {
                                (*in)[i].DeepCopyInto(&(*out)[i])
                        }
diff --git 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/apisixconsumer.go
 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/apisixconsumer.go
new file mode 100644
index 0000000..dff56aa
--- /dev/null
+++ 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/apisixconsumer.go
@@ -0,0 +1,195 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed 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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v2alpha1
+
+import (
+       "context"
+       "time"
+
+       v2alpha1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1"
+       scheme 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned/scheme"
+       v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       types "k8s.io/apimachinery/pkg/types"
+       watch "k8s.io/apimachinery/pkg/watch"
+       rest "k8s.io/client-go/rest"
+)
+
+// ApisixConsumersGetter has a method to return a ApisixConsumerInterface.
+// A group's client should implement this interface.
+type ApisixConsumersGetter interface {
+       ApisixConsumers(namespace string) ApisixConsumerInterface
+}
+
+// ApisixConsumerInterface has methods to work with ApisixConsumer resources.
+type ApisixConsumerInterface interface {
+       Create(ctx context.Context, apisixConsumer *v2alpha1.ApisixConsumer, 
opts v1.CreateOptions) (*v2alpha1.ApisixConsumer, error)
+       Update(ctx context.Context, apisixConsumer *v2alpha1.ApisixConsumer, 
opts v1.UpdateOptions) (*v2alpha1.ApisixConsumer, error)
+       UpdateStatus(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.UpdateOptions) (*v2alpha1.ApisixConsumer, 
error)
+       Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
+       DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts 
v1.ListOptions) error
+       Get(ctx context.Context, name string, opts v1.GetOptions) 
(*v2alpha1.ApisixConsumer, error)
+       List(ctx context.Context, opts v1.ListOptions) 
(*v2alpha1.ApisixConsumerList, error)
+       Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
+       Patch(ctx context.Context, name string, pt types.PatchType, data 
[]byte, opts v1.PatchOptions, subresources ...string) (result 
*v2alpha1.ApisixConsumer, err error)
+       ApisixConsumerExpansion
+}
+
+// apisixConsumers implements ApisixConsumerInterface
+type apisixConsumers struct {
+       client rest.Interface
+       ns     string
+}
+
+// newApisixConsumers returns a ApisixConsumers
+func newApisixConsumers(c *ApisixV2alpha1Client, namespace string) 
*apisixConsumers {
+       return &apisixConsumers{
+               client: c.RESTClient(),
+               ns:     namespace,
+       }
+}
+
+// Get takes name of the apisixConsumer, and returns the corresponding 
apisixConsumer object, and an error if there is any.
+func (c *apisixConsumers) Get(ctx context.Context, name string, options 
v1.GetOptions) (result *v2alpha1.ApisixConsumer, err error) {
+       result = &v2alpha1.ApisixConsumer{}
+       err = c.client.Get().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               Name(name).
+               VersionedParams(&options, scheme.ParameterCodec).
+               Do(ctx).
+               Into(result)
+       return
+}
+
+// List takes label and field selectors, and returns the list of 
ApisixConsumers that match those selectors.
+func (c *apisixConsumers) List(ctx context.Context, opts v1.ListOptions) 
(result *v2alpha1.ApisixConsumerList, err error) {
+       var timeout time.Duration
+       if opts.TimeoutSeconds != nil {
+               timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+       }
+       result = &v2alpha1.ApisixConsumerList{}
+       err = c.client.Get().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Timeout(timeout).
+               Do(ctx).
+               Into(result)
+       return
+}
+
+// Watch returns a watch.Interface that watches the requested apisixConsumers.
+func (c *apisixConsumers) Watch(ctx context.Context, opts v1.ListOptions) 
(watch.Interface, error) {
+       var timeout time.Duration
+       if opts.TimeoutSeconds != nil {
+               timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+       }
+       opts.Watch = true
+       return c.client.Get().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Timeout(timeout).
+               Watch(ctx)
+}
+
+// Create takes the representation of a apisixConsumer and creates it.  
Returns the server's representation of the apisixConsumer, and an error, if 
there is any.
+func (c *apisixConsumers) Create(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.CreateOptions) (result 
*v2alpha1.ApisixConsumer, err error) {
+       result = &v2alpha1.ApisixConsumer{}
+       err = c.client.Post().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Body(apisixConsumer).
+               Do(ctx).
+               Into(result)
+       return
+}
+
+// Update takes the representation of a apisixConsumer and updates it. Returns 
the server's representation of the apisixConsumer, and an error, if there is 
any.
+func (c *apisixConsumers) Update(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.UpdateOptions) (result 
*v2alpha1.ApisixConsumer, err error) {
+       result = &v2alpha1.ApisixConsumer{}
+       err = c.client.Put().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               Name(apisixConsumer.Name).
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Body(apisixConsumer).
+               Do(ctx).
+               Into(result)
+       return
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating 
UpdateStatus().
+func (c *apisixConsumers) UpdateStatus(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.UpdateOptions) (result 
*v2alpha1.ApisixConsumer, err error) {
+       result = &v2alpha1.ApisixConsumer{}
+       err = c.client.Put().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               Name(apisixConsumer.Name).
+               SubResource("status").
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Body(apisixConsumer).
+               Do(ctx).
+               Into(result)
+       return
+}
+
+// Delete takes name of the apisixConsumer and deletes it. Returns an error if 
one occurs.
+func (c *apisixConsumers) Delete(ctx context.Context, name string, opts 
v1.DeleteOptions) error {
+       return c.client.Delete().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               Name(name).
+               Body(&opts).
+               Do(ctx).
+               Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *apisixConsumers) DeleteCollection(ctx context.Context, opts 
v1.DeleteOptions, listOpts v1.ListOptions) error {
+       var timeout time.Duration
+       if listOpts.TimeoutSeconds != nil {
+               timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
+       }
+       return c.client.Delete().
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               VersionedParams(&listOpts, scheme.ParameterCodec).
+               Timeout(timeout).
+               Body(&opts).
+               Do(ctx).
+               Error()
+}
+
+// Patch applies the patch and returns the patched apisixConsumer.
+func (c *apisixConsumers) Patch(ctx context.Context, name string, pt 
types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) 
(result *v2alpha1.ApisixConsumer, err error) {
+       result = &v2alpha1.ApisixConsumer{}
+       err = c.client.Patch(pt).
+               Namespace(c.ns).
+               Resource("apisixconsumers").
+               Name(name).
+               SubResource(subresources...).
+               VersionedParams(&opts, scheme.ParameterCodec).
+               Body(data).
+               Do(ctx).
+               Into(result)
+       return
+}
diff --git 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/config_client.go
 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/config_client.go
index 1197eb0..bbab116 100644
--- 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/config_client.go
+++ 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/config_client.go
@@ -27,6 +27,7 @@ import (
 type ApisixV2alpha1Interface interface {
        RESTClient() rest.Interface
        ApisixClusterConfigsGetter
+       ApisixConsumersGetter
        ApisixRoutesGetter
 }
 
@@ -39,6 +40,10 @@ func (c *ApisixV2alpha1Client) ApisixClusterConfigs() 
ApisixClusterConfigInterfa
        return newApisixClusterConfigs(c)
 }
 
+func (c *ApisixV2alpha1Client) ApisixConsumers(namespace string) 
ApisixConsumerInterface {
+       return newApisixConsumers(c, namespace)
+}
+
 func (c *ApisixV2alpha1Client) ApisixRoutes(namespace string) 
ApisixRouteInterface {
        return newApisixRoutes(c, namespace)
 }
diff --git 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_apisixconsumer.go
 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_apisixconsumer.go
new file mode 100644
index 0000000..fef2ab8
--- /dev/null
+++ 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_apisixconsumer.go
@@ -0,0 +1,142 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed 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.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+       "context"
+
+       v2alpha1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1"
+       v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       labels "k8s.io/apimachinery/pkg/labels"
+       schema "k8s.io/apimachinery/pkg/runtime/schema"
+       types "k8s.io/apimachinery/pkg/types"
+       watch "k8s.io/apimachinery/pkg/watch"
+       testing "k8s.io/client-go/testing"
+)
+
+// FakeApisixConsumers implements ApisixConsumerInterface
+type FakeApisixConsumers struct {
+       Fake *FakeApisixV2alpha1
+       ns   string
+}
+
+var apisixconsumersResource = schema.GroupVersionResource{Group: 
"apisix.apache.org", Version: "v2alpha1", Resource: "apisixconsumers"}
+
+var apisixconsumersKind = schema.GroupVersionKind{Group: "apisix.apache.org", 
Version: "v2alpha1", Kind: "ApisixConsumer"}
+
+// Get takes name of the apisixConsumer, and returns the corresponding 
apisixConsumer object, and an error if there is any.
+func (c *FakeApisixConsumers) Get(ctx context.Context, name string, options 
v1.GetOptions) (result *v2alpha1.ApisixConsumer, err error) {
+       obj, err := c.Fake.
+               Invokes(testing.NewGetAction(apisixconsumersResource, c.ns, 
name), &v2alpha1.ApisixConsumer{})
+
+       if obj == nil {
+               return nil, err
+       }
+       return obj.(*v2alpha1.ApisixConsumer), err
+}
+
+// List takes label and field selectors, and returns the list of 
ApisixConsumers that match those selectors.
+func (c *FakeApisixConsumers) List(ctx context.Context, opts v1.ListOptions) 
(result *v2alpha1.ApisixConsumerList, err error) {
+       obj, err := c.Fake.
+               Invokes(testing.NewListAction(apisixconsumersResource, 
apisixconsumersKind, c.ns, opts), &v2alpha1.ApisixConsumerList{})
+
+       if obj == nil {
+               return nil, err
+       }
+
+       label, _, _ := testing.ExtractFromListOptions(opts)
+       if label == nil {
+               label = labels.Everything()
+       }
+       list := &v2alpha1.ApisixConsumerList{ListMeta: 
obj.(*v2alpha1.ApisixConsumerList).ListMeta}
+       for _, item := range obj.(*v2alpha1.ApisixConsumerList).Items {
+               if label.Matches(labels.Set(item.Labels)) {
+                       list.Items = append(list.Items, item)
+               }
+       }
+       return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested apisixConsumers.
+func (c *FakeApisixConsumers) Watch(ctx context.Context, opts v1.ListOptions) 
(watch.Interface, error) {
+       return c.Fake.
+               InvokesWatch(testing.NewWatchAction(apisixconsumersResource, 
c.ns, opts))
+
+}
+
+// Create takes the representation of a apisixConsumer and creates it.  
Returns the server's representation of the apisixConsumer, and an error, if 
there is any.
+func (c *FakeApisixConsumers) Create(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.CreateOptions) (result 
*v2alpha1.ApisixConsumer, err error) {
+       obj, err := c.Fake.
+               Invokes(testing.NewCreateAction(apisixconsumersResource, c.ns, 
apisixConsumer), &v2alpha1.ApisixConsumer{})
+
+       if obj == nil {
+               return nil, err
+       }
+       return obj.(*v2alpha1.ApisixConsumer), err
+}
+
+// Update takes the representation of a apisixConsumer and updates it. Returns 
the server's representation of the apisixConsumer, and an error, if there is 
any.
+func (c *FakeApisixConsumers) Update(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.UpdateOptions) (result 
*v2alpha1.ApisixConsumer, err error) {
+       obj, err := c.Fake.
+               Invokes(testing.NewUpdateAction(apisixconsumersResource, c.ns, 
apisixConsumer), &v2alpha1.ApisixConsumer{})
+
+       if obj == nil {
+               return nil, err
+       }
+       return obj.(*v2alpha1.ApisixConsumer), err
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating 
UpdateStatus().
+func (c *FakeApisixConsumers) UpdateStatus(ctx context.Context, apisixConsumer 
*v2alpha1.ApisixConsumer, opts v1.UpdateOptions) (*v2alpha1.ApisixConsumer, 
error) {
+       obj, err := c.Fake.
+               
Invokes(testing.NewUpdateSubresourceAction(apisixconsumersResource, "status", 
c.ns, apisixConsumer), &v2alpha1.ApisixConsumer{})
+
+       if obj == nil {
+               return nil, err
+       }
+       return obj.(*v2alpha1.ApisixConsumer), err
+}
+
+// Delete takes name of the apisixConsumer and deletes it. Returns an error if 
one occurs.
+func (c *FakeApisixConsumers) Delete(ctx context.Context, name string, opts 
v1.DeleteOptions) error {
+       _, err := c.Fake.
+               Invokes(testing.NewDeleteAction(apisixconsumersResource, c.ns, 
name), &v2alpha1.ApisixConsumer{})
+
+       return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeApisixConsumers) DeleteCollection(ctx context.Context, opts 
v1.DeleteOptions, listOpts v1.ListOptions) error {
+       action := testing.NewDeleteCollectionAction(apisixconsumersResource, 
c.ns, listOpts)
+
+       _, err := c.Fake.Invokes(action, &v2alpha1.ApisixConsumerList{})
+       return err
+}
+
+// Patch applies the patch and returns the patched apisixConsumer.
+func (c *FakeApisixConsumers) Patch(ctx context.Context, name string, pt 
types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) 
(result *v2alpha1.ApisixConsumer, err error) {
+       obj, err := c.Fake.
+               
Invokes(testing.NewPatchSubresourceAction(apisixconsumersResource, c.ns, name, 
pt, data, subresources...), &v2alpha1.ApisixConsumer{})
+
+       if obj == nil {
+               return nil, err
+       }
+       return obj.(*v2alpha1.ApisixConsumer), err
+}
diff --git 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_config_client.go
 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_config_client.go
index 16cabaf..e7fef39 100644
--- 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_config_client.go
+++ 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/fake/fake_config_client.go
@@ -32,6 +32,10 @@ func (c *FakeApisixV2alpha1) ApisixClusterConfigs() 
v2alpha1.ApisixClusterConfig
        return &FakeApisixClusterConfigs{c}
 }
 
+func (c *FakeApisixV2alpha1) ApisixConsumers(namespace string) 
v2alpha1.ApisixConsumerInterface {
+       return &FakeApisixConsumers{c, namespace}
+}
+
 func (c *FakeApisixV2alpha1) ApisixRoutes(namespace string) 
v2alpha1.ApisixRouteInterface {
        return &FakeApisixRoutes{c, namespace}
 }
diff --git 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/generated_expansion.go
 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/generated_expansion.go
index b1775c9..6f0893a 100644
--- 
a/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/generated_expansion.go
+++ 
b/pkg/kube/apisix/client/clientset/versioned/typed/config/v2alpha1/generated_expansion.go
@@ -20,4 +20,6 @@ package v2alpha1
 
 type ApisixClusterConfigExpansion interface{}
 
+type ApisixConsumerExpansion interface{}
+
 type ApisixRouteExpansion interface{}
diff --git 
a/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/apisixconsumer.go
 
b/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/apisixconsumer.go
new file mode 100644
index 0000000..110b505
--- /dev/null
+++ 
b/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/apisixconsumer.go
@@ -0,0 +1,90 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed 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.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v2alpha1
+
+import (
+       "context"
+       time "time"
+
+       configv2alpha1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1"
+       versioned 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned"
+       internalinterfaces 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/informers/externalversions/internalinterfaces"
+       v2alpha1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/listers/config/v2alpha1"
+       v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       runtime "k8s.io/apimachinery/pkg/runtime"
+       watch "k8s.io/apimachinery/pkg/watch"
+       cache "k8s.io/client-go/tools/cache"
+)
+
+// ApisixConsumerInformer provides access to a shared informer and lister for
+// ApisixConsumers.
+type ApisixConsumerInformer interface {
+       Informer() cache.SharedIndexInformer
+       Lister() v2alpha1.ApisixConsumerLister
+}
+
+type apisixConsumerInformer struct {
+       factory          internalinterfaces.SharedInformerFactory
+       tweakListOptions internalinterfaces.TweakListOptionsFunc
+       namespace        string
+}
+
+// NewApisixConsumerInformer constructs a new informer for ApisixConsumer type.
+// Always prefer using an informer factory to get a shared informer instead of 
getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewApisixConsumerInformer(client versioned.Interface, namespace string, 
resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+       return NewFilteredApisixConsumerInformer(client, namespace, 
resyncPeriod, indexers, nil)
+}
+
+// NewFilteredApisixConsumerInformer constructs a new informer for 
ApisixConsumer type.
+// Always prefer using an informer factory to get a shared informer instead of 
getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredApisixConsumerInformer(client versioned.Interface, namespace 
string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions 
internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+       return cache.NewSharedIndexInformer(
+               &cache.ListWatch{
+                       ListFunc: func(options v1.ListOptions) (runtime.Object, 
error) {
+                               if tweakListOptions != nil {
+                                       tweakListOptions(&options)
+                               }
+                               return 
client.ApisixV2alpha1().ApisixConsumers(namespace).List(context.TODO(), options)
+                       },
+                       WatchFunc: func(options v1.ListOptions) 
(watch.Interface, error) {
+                               if tweakListOptions != nil {
+                                       tweakListOptions(&options)
+                               }
+                               return 
client.ApisixV2alpha1().ApisixConsumers(namespace).Watch(context.TODO(), 
options)
+                       },
+               },
+               &configv2alpha1.ApisixConsumer{},
+               resyncPeriod,
+               indexers,
+       )
+}
+
+func (f *apisixConsumerInformer) defaultInformer(client versioned.Interface, 
resyncPeriod time.Duration) cache.SharedIndexInformer {
+       return NewFilteredApisixConsumerInformer(client, f.namespace, 
resyncPeriod, cache.Indexers{cache.NamespaceIndex: 
cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *apisixConsumerInformer) Informer() cache.SharedIndexInformer {
+       return f.factory.InformerFor(&configv2alpha1.ApisixConsumer{}, 
f.defaultInformer)
+}
+
+func (f *apisixConsumerInformer) Lister() v2alpha1.ApisixConsumerLister {
+       return v2alpha1.NewApisixConsumerLister(f.Informer().GetIndexer())
+}
diff --git 
a/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/interface.go
 
b/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/interface.go
index a787523..4935672 100644
--- 
a/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/interface.go
+++ 
b/pkg/kube/apisix/client/informers/externalversions/config/v2alpha1/interface.go
@@ -26,6 +26,8 @@ import (
 type Interface interface {
        // ApisixClusterConfigs returns a ApisixClusterConfigInformer.
        ApisixClusterConfigs() ApisixClusterConfigInformer
+       // ApisixConsumers returns a ApisixConsumerInformer.
+       ApisixConsumers() ApisixConsumerInformer
        // ApisixRoutes returns a ApisixRouteInformer.
        ApisixRoutes() ApisixRouteInformer
 }
@@ -46,6 +48,11 @@ func (v *version) ApisixClusterConfigs() 
ApisixClusterConfigInformer {
        return &apisixClusterConfigInformer{factory: v.factory, 
tweakListOptions: v.tweakListOptions}
 }
 
+// ApisixConsumers returns a ApisixConsumerInformer.
+func (v *version) ApisixConsumers() ApisixConsumerInformer {
+       return &apisixConsumerInformer{factory: v.factory, namespace: 
v.namespace, tweakListOptions: v.tweakListOptions}
+}
+
 // ApisixRoutes returns a ApisixRouteInformer.
 func (v *version) ApisixRoutes() ApisixRouteInformer {
        return &apisixRouteInformer{factory: v.factory, namespace: v.namespace, 
tweakListOptions: v.tweakListOptions}
diff --git a/pkg/kube/apisix/client/informers/externalversions/generic.go 
b/pkg/kube/apisix/client/informers/externalversions/generic.go
index e24f2f8..f5164e4 100644
--- a/pkg/kube/apisix/client/informers/externalversions/generic.go
+++ b/pkg/kube/apisix/client/informers/externalversions/generic.go
@@ -64,6 +64,8 @@ func (f *sharedInformerFactory) ForResource(resource 
schema.GroupVersionResource
                // Group=apisix.apache.org, Version=v2alpha1
        case v2alpha1.SchemeGroupVersion.WithResource("apisixclusterconfigs"):
                return &genericInformer{resource: resource.GroupResource(), 
informer: f.Apisix().V2alpha1().ApisixClusterConfigs().Informer()}, nil
+       case v2alpha1.SchemeGroupVersion.WithResource("apisixconsumers"):
+               return &genericInformer{resource: resource.GroupResource(), 
informer: f.Apisix().V2alpha1().ApisixConsumers().Informer()}, nil
        case v2alpha1.SchemeGroupVersion.WithResource("apisixroutes"):
                return &genericInformer{resource: resource.GroupResource(), 
informer: f.Apisix().V2alpha1().ApisixRoutes().Informer()}, nil
 
diff --git a/pkg/kube/apisix/client/listers/config/v2alpha1/apisixconsumer.go 
b/pkg/kube/apisix/client/listers/config/v2alpha1/apisixconsumer.go
new file mode 100644
index 0000000..c94b222
--- /dev/null
+++ b/pkg/kube/apisix/client/listers/config/v2alpha1/apisixconsumer.go
@@ -0,0 +1,99 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed 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.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v2alpha1
+
+import (
+       v2alpha1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1"
+       "k8s.io/apimachinery/pkg/api/errors"
+       "k8s.io/apimachinery/pkg/labels"
+       "k8s.io/client-go/tools/cache"
+)
+
+// ApisixConsumerLister helps list ApisixConsumers.
+// All objects returned here must be treated as read-only.
+type ApisixConsumerLister interface {
+       // List lists all ApisixConsumers in the indexer.
+       // Objects returned here must be treated as read-only.
+       List(selector labels.Selector) (ret []*v2alpha1.ApisixConsumer, err 
error)
+       // ApisixConsumers returns an object that can list and get 
ApisixConsumers.
+       ApisixConsumers(namespace string) ApisixConsumerNamespaceLister
+       ApisixConsumerListerExpansion
+}
+
+// apisixConsumerLister implements the ApisixConsumerLister interface.
+type apisixConsumerLister struct {
+       indexer cache.Indexer
+}
+
+// NewApisixConsumerLister returns a new ApisixConsumerLister.
+func NewApisixConsumerLister(indexer cache.Indexer) ApisixConsumerLister {
+       return &apisixConsumerLister{indexer: indexer}
+}
+
+// List lists all ApisixConsumers in the indexer.
+func (s *apisixConsumerLister) List(selector labels.Selector) (ret 
[]*v2alpha1.ApisixConsumer, err error) {
+       err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+               ret = append(ret, m.(*v2alpha1.ApisixConsumer))
+       })
+       return ret, err
+}
+
+// ApisixConsumers returns an object that can list and get ApisixConsumers.
+func (s *apisixConsumerLister) ApisixConsumers(namespace string) 
ApisixConsumerNamespaceLister {
+       return apisixConsumerNamespaceLister{indexer: s.indexer, namespace: 
namespace}
+}
+
+// ApisixConsumerNamespaceLister helps list and get ApisixConsumers.
+// All objects returned here must be treated as read-only.
+type ApisixConsumerNamespaceLister interface {
+       // List lists all ApisixConsumers in the indexer for a given namespace.
+       // Objects returned here must be treated as read-only.
+       List(selector labels.Selector) (ret []*v2alpha1.ApisixConsumer, err 
error)
+       // Get retrieves the ApisixConsumer from the indexer for a given 
namespace and name.
+       // Objects returned here must be treated as read-only.
+       Get(name string) (*v2alpha1.ApisixConsumer, error)
+       ApisixConsumerNamespaceListerExpansion
+}
+
+// apisixConsumerNamespaceLister implements the ApisixConsumerNamespaceLister
+// interface.
+type apisixConsumerNamespaceLister struct {
+       indexer   cache.Indexer
+       namespace string
+}
+
+// List lists all ApisixConsumers in the indexer for a given namespace.
+func (s apisixConsumerNamespaceLister) List(selector labels.Selector) (ret 
[]*v2alpha1.ApisixConsumer, err error) {
+       err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m 
interface{}) {
+               ret = append(ret, m.(*v2alpha1.ApisixConsumer))
+       })
+       return ret, err
+}
+
+// Get retrieves the ApisixConsumer from the indexer for a given namespace and 
name.
+func (s apisixConsumerNamespaceLister) Get(name string) 
(*v2alpha1.ApisixConsumer, error) {
+       obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+       if err != nil {
+               return nil, err
+       }
+       if !exists {
+               return nil, 
errors.NewNotFound(v2alpha1.Resource("apisixconsumer"), name)
+       }
+       return obj.(*v2alpha1.ApisixConsumer), nil
+}
diff --git 
a/pkg/kube/apisix/client/listers/config/v2alpha1/expansion_generated.go 
b/pkg/kube/apisix/client/listers/config/v2alpha1/expansion_generated.go
index 5d5ca57..b090043 100644
--- a/pkg/kube/apisix/client/listers/config/v2alpha1/expansion_generated.go
+++ b/pkg/kube/apisix/client/listers/config/v2alpha1/expansion_generated.go
@@ -22,6 +22,14 @@ package v2alpha1
 // ApisixClusterConfigLister.
 type ApisixClusterConfigListerExpansion interface{}
 
+// ApisixConsumerListerExpansion allows custom methods to be added to
+// ApisixConsumerLister.
+type ApisixConsumerListerExpansion interface{}
+
+// ApisixConsumerNamespaceListerExpansion allows custom methods to be added to
+// ApisixConsumerNamespaceLister.
+type ApisixConsumerNamespaceListerExpansion interface{}
+
 // ApisixRouteListerExpansion allows custom methods to be added to
 // ApisixRouteLister.
 type ApisixRouteListerExpansion interface{}
diff --git a/samples/deploy/crd/v1beta1/ApisixConsumer.yaml 
b/samples/deploy/crd/v1beta1/ApisixConsumer.yaml
new file mode 100644
index 0000000..11b605b
--- /dev/null
+++ b/samples/deploy/crd/v1beta1/ApisixConsumer.yaml
@@ -0,0 +1,100 @@
+#
+# 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.
+#
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: apisixconsumers.apisix.apache.org
+spec:
+  group: apisix.apache.org
+  versions:
+    - name: v2alpha1
+      served: true
+      storage: true
+  scope: Namespaced
+  names:
+    plural: apisixconsumers
+    singular: apisixconsumer
+    kind: ApisixConsumer
+    shortNames:
+      - ac
+  preserveUnknownFields: false
+  subresources:
+    status: {}
+  validation:
+    openAPIV3Schema:
+      type: object
+      properties:
+        spec:
+          type: object
+          required:
+            - authParameter
+          properties:
+            authParameter:
+              type: object
+              oneOf:
+                - required: ["basicAuth"]
+                - required: ["keyAuth"]
+              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
diff --git a/samples/deploy/rbac/apisix_view_clusterrole.yaml 
b/samples/deploy/rbac/apisix_view_clusterrole.yaml
index afdf698..1bdfcd7 100644
--- a/samples/deploy/rbac/apisix_view_clusterrole.yaml
+++ b/samples/deploy/rbac/apisix_view_clusterrole.yaml
@@ -141,6 +141,7 @@ rules:
   - apisixtlses
   - apisixtlses/status
   - apisixclusterconfigs
+  - apisixconsumers
   verbs:
   - '*'
 - apiGroups:
diff --git a/test/e2e/scaffold/ingress.go b/test/e2e/scaffold/ingress.go
index da1d36e..9f6c02b 100644
--- a/test/e2e/scaffold/ingress.go
+++ b/test/e2e/scaffold/ingress.go
@@ -158,6 +158,7 @@ rules:
       - apisixtlses
       - apisixtlses/status
       - apisixclusterconfigs
+      - apisixconsumers
     verbs:
       - '*'
   - apiGroups:

Reply via email to