You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by kv...@apache.org on 2021/02/04 08:19:58 UTC

[apisix-ingress-controller] branch master updated: fix: ssl use cache (#203)

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

kvn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new e2f3541  fix: ssl use cache (#203)
e2f3541 is described below

commit e2f3541dcdf9c26fe54ab4ac6f2dc3dd059941c5
Author: kv <gx...@163.com>
AuthorDate: Thu Feb 4 16:18:15 2021 +0800

    fix: ssl use cache (#203)
    
    * fix: ssl use cache
    
    * fix: cert failed
    
    * add tls update & delete test case
    
    * fix: modify image
    
    * fix: add license header
    
    * fix: build error after merge
    
    * fix: unit test failed
    
    * fix: review & add dp test case
    
    * fix: revert ApisixTls
    
    * fix: e2e test failed
    
    * fix: build image failed
    
    * fix: e2e test failed
    
    * fix: e2e-test failed
    
    * fix: e2e test failed
    
    * fix: remove debug info
    
    * fix: remove debug info
    
    * fix:typo
    
    * fix: remove createResourceWithMethod
    
    * fix: http ports
---
 go.sum                                             |   1 +
 pkg/apisix/cache/memdb_test.go                     |   9 +-
 pkg/apisix/cache/schema.go                         |   2 +-
 pkg/apisix/resource.go                             |   1 +
 pkg/apisix/ssl.go                                  |   2 +-
 pkg/ingress/apisix/tls.go                          |   2 +-
 pkg/ingress/controller/apisix_tls.go               |  18 +-
 pkg/ingress/controller/controller.go               |   2 +-
 pkg/kube/apisix/apis/config/v1/register.go         |   4 +-
 pkg/kube/apisix/apis/config/v1/types.go            |  14 +-
 .../apisix/apis/config/v1/zz_generated.deepcopy.go |  32 +--
 .../versioned/typed/config/v1/apisixtls.go         |  94 ++++-----
 .../versioned/typed/config/v1/config_client.go     |   6 +-
 .../typed/config/v1/fake/fake_apisixtls.go         |  68 +++---
 .../typed/config/v1/fake/fake_config_client.go     |   4 +-
 .../typed/config/v1/generated_expansion.go         |   2 +-
 .../externalversions/config/v1/apisixtls.go        |  38 ++--
 .../externalversions/config/v1/interface.go        |  10 +-
 .../client/informers/externalversions/generic.go   |   4 +-
 .../apisix/client/listers/config/v1/apisixtls.go   |  66 +++---
 .../listers/config/v1/expansion_generated.go       |  12 +-
 pkg/types/apisix/v1/types.go                       |  13 +-
 test/e2e/ingress/resourcepushing.go                |  22 +-
 test/e2e/ingress/ssl.go                            | 235 +++++++++++++++++++++
 test/e2e/scaffold/apisix.go                        |  26 +++
 test/e2e/scaffold/crd.go                           |  24 +++
 test/e2e/scaffold/scaffold.go                      |  28 ++-
 test/e2e/scaffold/ssl.go                           |  76 +++++++
 test/e2e/testdata/apisix-gw-config.yaml            |   2 +-
 29 files changed, 605 insertions(+), 212 deletions(-)

diff --git a/go.sum b/go.sum
index 670ae5c..542312f 100644
--- a/go.sum
+++ b/go.sum
@@ -42,6 +42,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/api7/ingress-controller v0.1.0-rc1 h1:6EjrBu0r+ccVfYTnpGYj1txz1DJCJ/Q/k8pHigRkeu0=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
diff --git a/pkg/apisix/cache/memdb_test.go b/pkg/apisix/cache/memdb_test.go
index f36b3a5..47e7914 100644
--- a/pkg/apisix/cache/memdb_test.go
+++ b/pkg/apisix/cache/memdb_test.go
@@ -134,7 +134,8 @@ func TestMemDBCacheSSL(t *testing.T) {
 	assert.Nil(t, err, "NewMemDBCache")
 
 	s1 := &v1.Ssl{
-		ID: "abc",
+		ID:       "abc",
+		FullName: "abc",
 	}
 	assert.Nil(t, c.InsertSSL(s1), "inserting ssl 1")
 
@@ -142,10 +143,12 @@ func TestMemDBCacheSSL(t *testing.T) {
 	assert.Equal(t, s1, s)
 
 	s2 := &v1.Ssl{
-		ID: "def",
+		ID:       "def",
+		FullName: "def",
 	}
 	s3 := &v1.Ssl{
-		ID: "ghi",
+		ID:       "ghi",
+		FullName: "ghi",
 	}
 	assert.Nil(t, c.InsertSSL(s2), "inserting ssl 2")
 	assert.Nil(t, c.InsertSSL(s3), "inserting ssl 3")
diff --git a/pkg/apisix/cache/schema.go b/pkg/apisix/cache/schema.go
index f7fa6f0..79b483e 100644
--- a/pkg/apisix/cache/schema.go
+++ b/pkg/apisix/cache/schema.go
@@ -87,7 +87,7 @@ var (
 					"id": {
 						Name:    "id",
 						Unique:  true,
-						Indexer: &memdb.StringFieldIndex{Field: "ID"},
+						Indexer: &memdb.StringFieldIndex{Field: "FullName"},
 					},
 				},
 			},
diff --git a/pkg/apisix/resource.go b/pkg/apisix/resource.go
index 27f8589..19aa87d 100644
--- a/pkg/apisix/resource.go
+++ b/pkg/apisix/resource.go
@@ -192,6 +192,7 @@ func (i *item) ssl(clusterName string) (*v1.Ssl, error) {
 	id := list[len(list)-1]
 	ssl.ID = id
 	ssl.Group = clusterName
+	ssl.FullName = id
 	return &ssl, nil
 }
 
diff --git a/pkg/apisix/ssl.go b/pkg/apisix/ssl.go
index 434fc8c..21ad5ef 100644
--- a/pkg/apisix/ssl.go
+++ b/pkg/apisix/ssl.go
@@ -138,6 +138,7 @@ func (s *sslClient) Create(ctx context.Context, obj *v1.Ssl) (*v1.Ssl, error) {
 	log.Infow("try to create ssl",
 		zap.String("cluster", s.clusterName),
 		zap.String("url", s.url),
+		zap.String("id", obj.ID),
 	)
 	if err := s.cluster.HasSynced(ctx); err != nil {
 		return nil, err
@@ -231,7 +232,6 @@ func (s *sslClient) Update(ctx context.Context, obj *v1.Ssl) (*v1.Ssl, error) {
 	if err := s.cluster.cache.InsertSSL(ssl); err != nil {
 		log.Errorf("failed to reflect ssl update to cache: %s", err)
 		return nil, err
-
 	}
 	return ssl, nil
 }
diff --git a/pkg/ingress/apisix/tls.go b/pkg/ingress/apisix/tls.go
index 4796259..eb547b6 100644
--- a/pkg/ingress/apisix/tls.go
+++ b/pkg/ingress/apisix/tls.go
@@ -26,7 +26,7 @@ import (
 	apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
 
-type ApisixTLSCRD configv1.ApisixTLS
+type ApisixTLSCRD configv1.ApisixTls
 
 // Convert convert to  apisix.Ssl from ingress.ApisixTls CRD
 func (as *ApisixTLSCRD) Convert(sc Secreter) (*apisix.Ssl, error) {
diff --git a/pkg/ingress/controller/apisix_tls.go b/pkg/ingress/controller/apisix_tls.go
index 4720c92..2871396 100644
--- a/pkg/ingress/controller/apisix_tls.go
+++ b/pkg/ingress/controller/apisix_tls.go
@@ -40,21 +40,21 @@ type ApisixTLSController struct {
 	controller      *Controller
 	kubeclientset   kubernetes.Interface
 	apisixClientset clientset.Interface
-	apisixTLSList   listersv1.ApisixTLSLister
+	apisixTLSList   listersv1.ApisixTlsLister
 	apisixTLSSynced cache.InformerSynced
 	workqueue       workqueue.RateLimitingInterface
 }
 
 type TlsQueueObj struct {
 	Key    string              `json:"key"`
-	OldObj *configv1.ApisixTLS `json:"old_obj"`
+	OldObj *configv1.ApisixTls `json:"old_obj"`
 	Ope    string              `json:"ope"` // add / update / delete
 }
 
 func BuildApisixTlsController(
 	kubeclientset kubernetes.Interface,
 	apisixTLSClientset clientset.Interface,
-	apisixTLSInformer informersv1.ApisixTLSInformer,
+	apisixTLSInformer informersv1.ApisixTlsInformer,
 	root *Controller) *ApisixTLSController {
 
 	runtime.Must(apisixscheme.AddToScheme(scheme.Scheme))
@@ -128,13 +128,13 @@ func (c *ApisixTLSController) syncHandler(tqo *TlsQueueObj) error {
 	}
 	apisixTlsYaml := tqo.OldObj
 	if tqo.Ope == state.Delete {
-		apisixIngressTls, _ := c.apisixTLSList.ApisixTLSs(namespace).Get(name)
+		apisixIngressTls, _ := c.apisixTLSList.ApisixTlses(namespace).Get(name)
 		if apisixIngressTls != nil && apisixIngressTls.ResourceVersion > tqo.OldObj.ResourceVersion {
 			log.Warnf("TLS %s has been covered when retry", tqo.Key)
 			return nil
 		}
 	} else {
-		apisixTlsYaml, err = c.apisixTLSList.ApisixTLSs(namespace).Get(name)
+		apisixTlsYaml, err = c.apisixTLSList.ApisixTlses(namespace).Get(name)
 		if err != nil {
 			if errors.IsNotFound(err) {
 				log.Infof("apisixTls %s is removed", tqo.Key)
@@ -172,8 +172,8 @@ func (c *ApisixTLSController) addFunc(obj interface{}) {
 }
 
 func (c *ApisixTLSController) updateFunc(oldObj, newObj interface{}) {
-	oldTls := oldObj.(*configv1.ApisixTLS)
-	newTls := newObj.(*configv1.ApisixTLS)
+	oldTls := oldObj.(*configv1.ApisixTls)
+	newTls := newObj.(*configv1.ApisixTls)
 	if oldTls.ResourceVersion == newTls.ResourceVersion {
 		return
 	}
@@ -191,13 +191,13 @@ func (c *ApisixTLSController) updateFunc(oldObj, newObj interface{}) {
 }
 
 func (c *ApisixTLSController) deleteFunc(obj interface{}) {
-	oldTls, ok := obj.(*configv1.ApisixTLS)
+	oldTls, ok := obj.(*configv1.ApisixTls)
 	if !ok {
 		oldState, ok := obj.(cache.DeletedFinalStateUnknown)
 		if !ok {
 			return
 		}
-		oldTls, ok = oldState.Obj.(*configv1.ApisixTLS)
+		oldTls, ok = oldState.Obj.(*configv1.ApisixTls)
 		if !ok {
 			return
 		}
diff --git a/pkg/ingress/controller/controller.go b/pkg/ingress/controller/controller.go
index 946e832..8160850 100644
--- a/pkg/ingress/controller/controller.go
+++ b/pkg/ingress/controller/controller.go
@@ -330,7 +330,7 @@ func (api6 *Api6Controller) ApisixTLS(controller *Controller) {
 	atc := BuildApisixTlsController(
 		api6.KubeClientSet,
 		api6.Api6ClientSet,
-		api6.SharedInformerFactory.Apisix().V1().ApisixTLSs(),
+		api6.SharedInformerFactory.Apisix().V1().ApisixTlses(),
 		controller)
 	if err := atc.Run(api6.Stop); err != nil {
 		log.Errorf("failed to run ApisixTlsController: %s", err)
diff --git a/pkg/kube/apisix/apis/config/v1/register.go b/pkg/kube/apisix/apis/config/v1/register.go
index 4c2b402..e9e0e18 100644
--- a/pkg/kube/apisix/apis/config/v1/register.go
+++ b/pkg/kube/apisix/apis/config/v1/register.go
@@ -50,8 +50,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 		&ApisixUpstreamList{},
 		&ApisixService{},
 		&ApisixServiceList{},
-		&ApisixTLS{},
-		&ApisixTLSList{},
+		&ApisixTls{},
+		&ApisixTlsList{},
 	)
 
 	// register the type in the scheme
diff --git a/pkg/kube/apisix/apis/config/v1/types.go b/pkg/kube/apisix/apis/config/v1/types.go
index 5b58e96..4275106 100644
--- a/pkg/kube/apisix/apis/config/v1/types.go
+++ b/pkg/kube/apisix/apis/config/v1/types.go
@@ -191,22 +191,22 @@ func (p *Config) DeepCopy() *Config {
 // +genclient:noStatus
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-// ApisixTLS defines SSL resource in APISIX.
-type ApisixTLS struct {
+// ApisixTls defines SSL resource in APISIX.
+type ApisixTls struct {
 	metav1.TypeMeta   `json:",inline" yaml:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
-	Spec              *ApisixTLSSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
+	Spec              *ApisixTlsSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type ApisixTLSList struct {
+type ApisixTlsList struct {
 	metav1.TypeMeta `json:",inline"`
 	metav1.ListMeta `json:"metadata"`
-	Items           []ApisixTLS `json:"items,omitempty"`
+	Items           []ApisixTls `json:"items,omitempty"`
 }
 
-// ApisixTLSSpec is the specification of ApisixSSL.
-type ApisixTLSSpec struct {
+// ApisixTlsSpec is the specification of ApisixSSL.
+type ApisixTlsSpec struct {
 	Hosts  []string     `json:"hosts,omitempty"`
 	Secret ApisixSecret `json:"secret,omitempty"`
 }
diff --git a/pkg/kube/apisix/apis/config/v1/zz_generated.deepcopy.go b/pkg/kube/apisix/apis/config/v1/zz_generated.deepcopy.go
index bb9e309..93784ed 100644
--- a/pkg/kube/apisix/apis/config/v1/zz_generated.deepcopy.go
+++ b/pkg/kube/apisix/apis/config/v1/zz_generated.deepcopy.go
@@ -215,30 +215,30 @@ func (in *ApisixServiceSpec) DeepCopy() *ApisixServiceSpec {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ApisixTLS) DeepCopyInto(out *ApisixTLS) {
+func (in *ApisixTls) DeepCopyInto(out *ApisixTls) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
 	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
 	if in.Spec != nil {
 		in, out := &in.Spec, &out.Spec
-		*out = new(ApisixTLSSpec)
+		*out = new(ApisixTlsSpec)
 		(*in).DeepCopyInto(*out)
 	}
 	return
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTLS.
-func (in *ApisixTLS) DeepCopy() *ApisixTLS {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTls.
+func (in *ApisixTls) DeepCopy() *ApisixTls {
 	if in == nil {
 		return nil
 	}
-	out := new(ApisixTLS)
+	out := new(ApisixTls)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ApisixTLS) DeepCopyObject() runtime.Object {
+func (in *ApisixTls) DeepCopyObject() runtime.Object {
 	if c := in.DeepCopy(); c != nil {
 		return c
 	}
@@ -246,13 +246,13 @@ func (in *ApisixTLS) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ApisixTLSList) DeepCopyInto(out *ApisixTLSList) {
+func (in *ApisixTlsList) DeepCopyInto(out *ApisixTlsList) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
 	in.ListMeta.DeepCopyInto(&out.ListMeta)
 	if in.Items != nil {
 		in, out := &in.Items, &out.Items
-		*out = make([]ApisixTLS, len(*in))
+		*out = make([]ApisixTls, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
@@ -260,18 +260,18 @@ func (in *ApisixTLSList) DeepCopyInto(out *ApisixTLSList) {
 	return
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTLSList.
-func (in *ApisixTLSList) DeepCopy() *ApisixTLSList {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTlsList.
+func (in *ApisixTlsList) DeepCopy() *ApisixTlsList {
 	if in == nil {
 		return nil
 	}
-	out := new(ApisixTLSList)
+	out := new(ApisixTlsList)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ApisixTLSList) DeepCopyObject() runtime.Object {
+func (in *ApisixTlsList) DeepCopyObject() runtime.Object {
 	if c := in.DeepCopy(); c != nil {
 		return c
 	}
@@ -279,7 +279,7 @@ func (in *ApisixTLSList) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ApisixTLSSpec) DeepCopyInto(out *ApisixTLSSpec) {
+func (in *ApisixTlsSpec) DeepCopyInto(out *ApisixTlsSpec) {
 	*out = *in
 	if in.Hosts != nil {
 		in, out := &in.Hosts, &out.Hosts
@@ -290,12 +290,12 @@ func (in *ApisixTLSSpec) DeepCopyInto(out *ApisixTLSSpec) {
 	return
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTLSSpec.
-func (in *ApisixTLSSpec) DeepCopy() *ApisixTLSSpec {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApisixTlsSpec.
+func (in *ApisixTlsSpec) DeepCopy() *ApisixTlsSpec {
 	if in == nil {
 		return nil
 	}
-	out := new(ApisixTLSSpec)
+	out := new(ApisixTlsSpec)
 	in.DeepCopyInto(out)
 	return out
 }
diff --git a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/apisixtls.go b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/apisixtls.go
index cc56194..7384b1f 100644
--- a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/apisixtls.go
+++ b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/apisixtls.go
@@ -30,45 +30,45 @@ import (
 	rest "k8s.io/client-go/rest"
 )
 
-// ApisixTLSsGetter has a method to return a ApisixTLSInterface.
+// ApisixTlsesGetter has a method to return a ApisixTlsInterface.
 // A group's client should implement this interface.
-type ApisixTLSsGetter interface {
-	ApisixTLSs(namespace string) ApisixTLSInterface
+type ApisixTlsesGetter interface {
+	ApisixTlses(namespace string) ApisixTlsInterface
 }
 
-// ApisixTLSInterface has methods to work with ApisixTLS resources.
-type ApisixTLSInterface interface {
-	Create(ctx context.Context, apisixTLS *v1.ApisixTLS, opts metav1.CreateOptions) (*v1.ApisixTLS, error)
-	Update(ctx context.Context, apisixTLS *v1.ApisixTLS, opts metav1.UpdateOptions) (*v1.ApisixTLS, error)
+// ApisixTlsInterface has methods to work with ApisixTls resources.
+type ApisixTlsInterface interface {
+	Create(ctx context.Context, apisixTls *v1.ApisixTls, opts metav1.CreateOptions) (*v1.ApisixTls, error)
+	Update(ctx context.Context, apisixTls *v1.ApisixTls, opts metav1.UpdateOptions) (*v1.ApisixTls, error)
 	Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
 	DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
-	Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ApisixTLS, error)
-	List(ctx context.Context, opts metav1.ListOptions) (*v1.ApisixTLSList, error)
+	Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ApisixTls, error)
+	List(ctx context.Context, opts metav1.ListOptions) (*v1.ApisixTlsList, error)
 	Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
-	Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ApisixTLS, err error)
-	ApisixTLSExpansion
+	Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ApisixTls, err error)
+	ApisixTlsExpansion
 }
 
-// apisixTLSs implements ApisixTLSInterface
-type apisixTLSs struct {
+// apisixTlses implements ApisixTlsInterface
+type apisixTlses struct {
 	client rest.Interface
 	ns     string
 }
 
-// newApisixTLSs returns a ApisixTLSs
-func newApisixTLSs(c *ApisixV1Client, namespace string) *apisixTLSs {
-	return &apisixTLSs{
+// newApisixTlses returns a ApisixTlses
+func newApisixTlses(c *ApisixV1Client, namespace string) *apisixTlses {
+	return &apisixTlses{
 		client: c.RESTClient(),
 		ns:     namespace,
 	}
 }
 
-// Get takes name of the apisixTLS, and returns the corresponding apisixTLS object, and an error if there is any.
-func (c *apisixTLSs) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ApisixTLS, err error) {
-	result = &v1.ApisixTLS{}
+// Get takes name of the apisixTls, and returns the corresponding apisixTls object, and an error if there is any.
+func (c *apisixTlses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ApisixTls, err error) {
+	result = &v1.ApisixTls{}
 	err = c.client.Get().
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		Name(name).
 		VersionedParams(&options, scheme.ParameterCodec).
 		Do(ctx).
@@ -76,16 +76,16 @@ func (c *apisixTLSs) Get(ctx context.Context, name string, options metav1.GetOpt
 	return
 }
 
-// List takes label and field selectors, and returns the list of ApisixTLSs that match those selectors.
-func (c *apisixTLSs) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ApisixTLSList, err error) {
+// List takes label and field selectors, and returns the list of ApisixTlses that match those selectors.
+func (c *apisixTlses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ApisixTlsList, err error) {
 	var timeout time.Duration
 	if opts.TimeoutSeconds != nil {
 		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
 	}
-	result = &v1.ApisixTLSList{}
+	result = &v1.ApisixTlsList{}
 	err = c.client.Get().
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		VersionedParams(&opts, scheme.ParameterCodec).
 		Timeout(timeout).
 		Do(ctx).
@@ -93,8 +93,8 @@ func (c *apisixTLSs) List(ctx context.Context, opts metav1.ListOptions) (result
 	return
 }
 
-// Watch returns a watch.Interface that watches the requested apisixTLSs.
-func (c *apisixTLSs) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
+// Watch returns a watch.Interface that watches the requested apisixTlses.
+func (c *apisixTlses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
 	var timeout time.Duration
 	if opts.TimeoutSeconds != nil {
 		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
@@ -102,44 +102,44 @@ func (c *apisixTLSs) Watch(ctx context.Context, opts metav1.ListOptions) (watch.
 	opts.Watch = true
 	return c.client.Get().
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		VersionedParams(&opts, scheme.ParameterCodec).
 		Timeout(timeout).
 		Watch(ctx)
 }
 
-// Create takes the representation of a apisixTLS and creates it.  Returns the server's representation of the apisixTLS, and an error, if there is any.
-func (c *apisixTLSs) Create(ctx context.Context, apisixTLS *v1.ApisixTLS, opts metav1.CreateOptions) (result *v1.ApisixTLS, err error) {
-	result = &v1.ApisixTLS{}
+// Create takes the representation of a apisixTls and creates it.  Returns the server's representation of the apisixTls, and an error, if there is any.
+func (c *apisixTlses) Create(ctx context.Context, apisixTls *v1.ApisixTls, opts metav1.CreateOptions) (result *v1.ApisixTls, err error) {
+	result = &v1.ApisixTls{}
 	err = c.client.Post().
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		VersionedParams(&opts, scheme.ParameterCodec).
-		Body(apisixTLS).
+		Body(apisixTls).
 		Do(ctx).
 		Into(result)
 	return
 }
 
-// Update takes the representation of a apisixTLS and updates it. Returns the server's representation of the apisixTLS, and an error, if there is any.
-func (c *apisixTLSs) Update(ctx context.Context, apisixTLS *v1.ApisixTLS, opts metav1.UpdateOptions) (result *v1.ApisixTLS, err error) {
-	result = &v1.ApisixTLS{}
+// Update takes the representation of a apisixTls and updates it. Returns the server's representation of the apisixTls, and an error, if there is any.
+func (c *apisixTlses) Update(ctx context.Context, apisixTls *v1.ApisixTls, opts metav1.UpdateOptions) (result *v1.ApisixTls, err error) {
+	result = &v1.ApisixTls{}
 	err = c.client.Put().
 		Namespace(c.ns).
-		Resource("apisixtlss").
-		Name(apisixTLS.Name).
+		Resource("apisixtlses").
+		Name(apisixTls.Name).
 		VersionedParams(&opts, scheme.ParameterCodec).
-		Body(apisixTLS).
+		Body(apisixTls).
 		Do(ctx).
 		Into(result)
 	return
 }
 
-// Delete takes name of the apisixTLS and deletes it. Returns an error if one occurs.
-func (c *apisixTLSs) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
+// Delete takes name of the apisixTls and deletes it. Returns an error if one occurs.
+func (c *apisixTlses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
 	return c.client.Delete().
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		Name(name).
 		Body(&opts).
 		Do(ctx).
@@ -147,14 +147,14 @@ func (c *apisixTLSs) Delete(ctx context.Context, name string, opts metav1.Delete
 }
 
 // DeleteCollection deletes a collection of objects.
-func (c *apisixTLSs) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
+func (c *apisixTlses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.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("apisixtlss").
+		Resource("apisixtlses").
 		VersionedParams(&listOpts, scheme.ParameterCodec).
 		Timeout(timeout).
 		Body(&opts).
@@ -162,12 +162,12 @@ func (c *apisixTLSs) DeleteCollection(ctx context.Context, opts metav1.DeleteOpt
 		Error()
 }
 
-// Patch applies the patch and returns the patched apisixTLS.
-func (c *apisixTLSs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ApisixTLS, err error) {
-	result = &v1.ApisixTLS{}
+// Patch applies the patch and returns the patched apisixTls.
+func (c *apisixTlses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ApisixTls, err error) {
+	result = &v1.ApisixTls{}
 	err = c.client.Patch(pt).
 		Namespace(c.ns).
-		Resource("apisixtlss").
+		Resource("apisixtlses").
 		Name(name).
 		SubResource(subresources...).
 		VersionedParams(&opts, scheme.ParameterCodec).
diff --git a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/config_client.go b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/config_client.go
index 99ba58f..66f2843 100644
--- a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/config_client.go
+++ b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/config_client.go
@@ -28,7 +28,7 @@ type ApisixV1Interface interface {
 	RESTClient() rest.Interface
 	ApisixRoutesGetter
 	ApisixServicesGetter
-	ApisixTLSsGetter
+	ApisixTlsesGetter
 	ApisixUpstreamsGetter
 }
 
@@ -45,8 +45,8 @@ func (c *ApisixV1Client) ApisixServices(namespace string) ApisixServiceInterface
 	return newApisixServices(c, namespace)
 }
 
-func (c *ApisixV1Client) ApisixTLSs(namespace string) ApisixTLSInterface {
-	return newApisixTLSs(c, namespace)
+func (c *ApisixV1Client) ApisixTlses(namespace string) ApisixTlsInterface {
+	return newApisixTlses(c, namespace)
 }
 
 func (c *ApisixV1Client) ApisixUpstreams(namespace string) ApisixUpstreamInterface {
diff --git a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_apisixtls.go b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_apisixtls.go
index 6724247..e45d880 100644
--- a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_apisixtls.go
+++ b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_apisixtls.go
@@ -30,31 +30,31 @@ import (
 	testing "k8s.io/client-go/testing"
 )
 
-// FakeApisixTLSs implements ApisixTLSInterface
-type FakeApisixTLSs struct {
+// FakeApisixTlses implements ApisixTlsInterface
+type FakeApisixTlses struct {
 	Fake *FakeApisixV1
 	ns   string
 }
 
-var apisixtlssResource = schema.GroupVersionResource{Group: "apisix.apache.org", Version: "v1", Resource: "apisixtlss"}
+var apisixtlsesResource = schema.GroupVersionResource{Group: "apisix.apache.org", Version: "v1", Resource: "apisixtlses"}
 
-var apisixtlssKind = schema.GroupVersionKind{Group: "apisix.apache.org", Version: "v1", Kind: "ApisixTLS"}
+var apisixtlsesKind = schema.GroupVersionKind{Group: "apisix.apache.org", Version: "v1", Kind: "ApisixTls"}
 
-// Get takes name of the apisixTLS, and returns the corresponding apisixTLS object, and an error if there is any.
-func (c *FakeApisixTLSs) Get(ctx context.Context, name string, options v1.GetOptions) (result *configv1.ApisixTLS, err error) {
+// Get takes name of the apisixTls, and returns the corresponding apisixTls object, and an error if there is any.
+func (c *FakeApisixTlses) Get(ctx context.Context, name string, options v1.GetOptions) (result *configv1.ApisixTls, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(apisixtlssResource, c.ns, name), &configv1.ApisixTLS{})
+		Invokes(testing.NewGetAction(apisixtlsesResource, c.ns, name), &configv1.ApisixTls{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*configv1.ApisixTLS), err
+	return obj.(*configv1.ApisixTls), err
 }
 
-// List takes label and field selectors, and returns the list of ApisixTLSs that match those selectors.
-func (c *FakeApisixTLSs) List(ctx context.Context, opts v1.ListOptions) (result *configv1.ApisixTLSList, err error) {
+// List takes label and field selectors, and returns the list of ApisixTlses that match those selectors.
+func (c *FakeApisixTlses) List(ctx context.Context, opts v1.ListOptions) (result *configv1.ApisixTlsList, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewListAction(apisixtlssResource, apisixtlssKind, c.ns, opts), &configv1.ApisixTLSList{})
+		Invokes(testing.NewListAction(apisixtlsesResource, apisixtlsesKind, c.ns, opts), &configv1.ApisixTlsList{})
 
 	if obj == nil {
 		return nil, err
@@ -64,8 +64,8 @@ func (c *FakeApisixTLSs) List(ctx context.Context, opts v1.ListOptions) (result
 	if label == nil {
 		label = labels.Everything()
 	}
-	list := &configv1.ApisixTLSList{ListMeta: obj.(*configv1.ApisixTLSList).ListMeta}
-	for _, item := range obj.(*configv1.ApisixTLSList).Items {
+	list := &configv1.ApisixTlsList{ListMeta: obj.(*configv1.ApisixTlsList).ListMeta}
+	for _, item := range obj.(*configv1.ApisixTlsList).Items {
 		if label.Matches(labels.Set(item.Labels)) {
 			list.Items = append(list.Items, item)
 		}
@@ -73,58 +73,58 @@ func (c *FakeApisixTLSs) List(ctx context.Context, opts v1.ListOptions) (result
 	return list, err
 }
 
-// Watch returns a watch.Interface that watches the requested apisixTLSs.
-func (c *FakeApisixTLSs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
+// Watch returns a watch.Interface that watches the requested apisixTlses.
+func (c *FakeApisixTlses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
 	return c.Fake.
-		InvokesWatch(testing.NewWatchAction(apisixtlssResource, c.ns, opts))
+		InvokesWatch(testing.NewWatchAction(apisixtlsesResource, c.ns, opts))
 
 }
 
-// Create takes the representation of a apisixTLS and creates it.  Returns the server's representation of the apisixTLS, and an error, if there is any.
-func (c *FakeApisixTLSs) Create(ctx context.Context, apisixTLS *configv1.ApisixTLS, opts v1.CreateOptions) (result *configv1.ApisixTLS, err error) {
+// Create takes the representation of a apisixTls and creates it.  Returns the server's representation of the apisixTls, and an error, if there is any.
+func (c *FakeApisixTlses) Create(ctx context.Context, apisixTls *configv1.ApisixTls, opts v1.CreateOptions) (result *configv1.ApisixTls, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(apisixtlssResource, c.ns, apisixTLS), &configv1.ApisixTLS{})
+		Invokes(testing.NewCreateAction(apisixtlsesResource, c.ns, apisixTls), &configv1.ApisixTls{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*configv1.ApisixTLS), err
+	return obj.(*configv1.ApisixTls), err
 }
 
-// Update takes the representation of a apisixTLS and updates it. Returns the server's representation of the apisixTLS, and an error, if there is any.
-func (c *FakeApisixTLSs) Update(ctx context.Context, apisixTLS *configv1.ApisixTLS, opts v1.UpdateOptions) (result *configv1.ApisixTLS, err error) {
+// Update takes the representation of a apisixTls and updates it. Returns the server's representation of the apisixTls, and an error, if there is any.
+func (c *FakeApisixTlses) Update(ctx context.Context, apisixTls *configv1.ApisixTls, opts v1.UpdateOptions) (result *configv1.ApisixTls, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(apisixtlssResource, c.ns, apisixTLS), &configv1.ApisixTLS{})
+		Invokes(testing.NewUpdateAction(apisixtlsesResource, c.ns, apisixTls), &configv1.ApisixTls{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*configv1.ApisixTLS), err
+	return obj.(*configv1.ApisixTls), err
 }
 
-// Delete takes name of the apisixTLS and deletes it. Returns an error if one occurs.
-func (c *FakeApisixTLSs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
+// Delete takes name of the apisixTls and deletes it. Returns an error if one occurs.
+func (c *FakeApisixTlses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
 	_, err := c.Fake.
-		Invokes(testing.NewDeleteAction(apisixtlssResource, c.ns, name), &configv1.ApisixTLS{})
+		Invokes(testing.NewDeleteAction(apisixtlsesResource, c.ns, name), &configv1.ApisixTls{})
 
 	return err
 }
 
 // DeleteCollection deletes a collection of objects.
-func (c *FakeApisixTLSs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
-	action := testing.NewDeleteCollectionAction(apisixtlssResource, c.ns, listOpts)
+func (c *FakeApisixTlses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
+	action := testing.NewDeleteCollectionAction(apisixtlsesResource, c.ns, listOpts)
 
-	_, err := c.Fake.Invokes(action, &configv1.ApisixTLSList{})
+	_, err := c.Fake.Invokes(action, &configv1.ApisixTlsList{})
 	return err
 }
 
-// Patch applies the patch and returns the patched apisixTLS.
-func (c *FakeApisixTLSs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *configv1.ApisixTLS, err error) {
+// Patch applies the patch and returns the patched apisixTls.
+func (c *FakeApisixTlses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *configv1.ApisixTls, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(apisixtlssResource, c.ns, name, pt, data, subresources...), &configv1.ApisixTLS{})
+		Invokes(testing.NewPatchSubresourceAction(apisixtlsesResource, c.ns, name, pt, data, subresources...), &configv1.ApisixTls{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*configv1.ApisixTLS), err
+	return obj.(*configv1.ApisixTls), err
 }
diff --git a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_config_client.go b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_config_client.go
index 6ae9a52..0d33dae 100644
--- a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_config_client.go
+++ b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/fake/fake_config_client.go
@@ -36,8 +36,8 @@ func (c *FakeApisixV1) ApisixServices(namespace string) v1.ApisixServiceInterfac
 	return &FakeApisixServices{c, namespace}
 }
 
-func (c *FakeApisixV1) ApisixTLSs(namespace string) v1.ApisixTLSInterface {
-	return &FakeApisixTLSs{c, namespace}
+func (c *FakeApisixV1) ApisixTlses(namespace string) v1.ApisixTlsInterface {
+	return &FakeApisixTlses{c, namespace}
 }
 
 func (c *FakeApisixV1) ApisixUpstreams(namespace string) v1.ApisixUpstreamInterface {
diff --git a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/generated_expansion.go b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/generated_expansion.go
index 8aedd13..c83626b 100644
--- a/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/generated_expansion.go
+++ b/pkg/kube/apisix/client/clientset/versioned/typed/config/v1/generated_expansion.go
@@ -22,6 +22,6 @@ type ApisixRouteExpansion interface{}
 
 type ApisixServiceExpansion interface{}
 
-type ApisixTLSExpansion interface{}
+type ApisixTlsExpansion interface{}
 
 type ApisixUpstreamExpansion interface{}
diff --git a/pkg/kube/apisix/client/informers/externalversions/config/v1/apisixtls.go b/pkg/kube/apisix/client/informers/externalversions/config/v1/apisixtls.go
index 0973864..79e53d9 100644
--- a/pkg/kube/apisix/client/informers/externalversions/config/v1/apisixtls.go
+++ b/pkg/kube/apisix/client/informers/externalversions/config/v1/apisixtls.go
@@ -32,59 +32,59 @@ import (
 	cache "k8s.io/client-go/tools/cache"
 )
 
-// ApisixTLSInformer provides access to a shared informer and lister for
-// ApisixTLSs.
-type ApisixTLSInformer interface {
+// ApisixTlsInformer provides access to a shared informer and lister for
+// ApisixTlses.
+type ApisixTlsInformer interface {
 	Informer() cache.SharedIndexInformer
-	Lister() v1.ApisixTLSLister
+	Lister() v1.ApisixTlsLister
 }
 
-type apisixTLSInformer struct {
+type apisixTlsInformer struct {
 	factory          internalinterfaces.SharedInformerFactory
 	tweakListOptions internalinterfaces.TweakListOptionsFunc
 	namespace        string
 }
 
-// NewApisixTLSInformer constructs a new informer for ApisixTLS type.
+// NewApisixTlsInformer constructs a new informer for ApisixTls 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 NewApisixTLSInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
-	return NewFilteredApisixTLSInformer(client, namespace, resyncPeriod, indexers, nil)
+func NewApisixTlsInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+	return NewFilteredApisixTlsInformer(client, namespace, resyncPeriod, indexers, nil)
 }
 
-// NewFilteredApisixTLSInformer constructs a new informer for ApisixTLS type.
+// NewFilteredApisixTlsInformer constructs a new informer for ApisixTls 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 NewFilteredApisixTLSInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+func NewFilteredApisixTlsInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
 	return cache.NewSharedIndexInformer(
 		&cache.ListWatch{
 			ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.ApisixV1().ApisixTLSs(namespace).List(context.TODO(), options)
+				return client.ApisixV1().ApisixTlses(namespace).List(context.TODO(), options)
 			},
 			WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.ApisixV1().ApisixTLSs(namespace).Watch(context.TODO(), options)
+				return client.ApisixV1().ApisixTlses(namespace).Watch(context.TODO(), options)
 			},
 		},
-		&configv1.ApisixTLS{},
+		&configv1.ApisixTls{},
 		resyncPeriod,
 		indexers,
 	)
 }
 
-func (f *apisixTLSInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
-	return NewFilteredApisixTLSInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+func (f *apisixTlsInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+	return NewFilteredApisixTlsInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
 }
 
-func (f *apisixTLSInformer) Informer() cache.SharedIndexInformer {
-	return f.factory.InformerFor(&configv1.ApisixTLS{}, f.defaultInformer)
+func (f *apisixTlsInformer) Informer() cache.SharedIndexInformer {
+	return f.factory.InformerFor(&configv1.ApisixTls{}, f.defaultInformer)
 }
 
-func (f *apisixTLSInformer) Lister() v1.ApisixTLSLister {
-	return v1.NewApisixTLSLister(f.Informer().GetIndexer())
+func (f *apisixTlsInformer) Lister() v1.ApisixTlsLister {
+	return v1.NewApisixTlsLister(f.Informer().GetIndexer())
 }
diff --git a/pkg/kube/apisix/client/informers/externalversions/config/v1/interface.go b/pkg/kube/apisix/client/informers/externalversions/config/v1/interface.go
index 01a2eac..ac21eb6 100644
--- a/pkg/kube/apisix/client/informers/externalversions/config/v1/interface.go
+++ b/pkg/kube/apisix/client/informers/externalversions/config/v1/interface.go
@@ -28,8 +28,8 @@ type Interface interface {
 	ApisixRoutes() ApisixRouteInformer
 	// ApisixServices returns a ApisixServiceInformer.
 	ApisixServices() ApisixServiceInformer
-	// ApisixTLSs returns a ApisixTLSInformer.
-	ApisixTLSs() ApisixTLSInformer
+	// ApisixTlses returns a ApisixTlsInformer.
+	ApisixTlses() ApisixTlsInformer
 	// ApisixUpstreams returns a ApisixUpstreamInformer.
 	ApisixUpstreams() ApisixUpstreamInformer
 }
@@ -55,9 +55,9 @@ func (v *version) ApisixServices() ApisixServiceInformer {
 	return &apisixServiceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
 }
 
-// ApisixTLSs returns a ApisixTLSInformer.
-func (v *version) ApisixTLSs() ApisixTLSInformer {
-	return &apisixTLSInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+// ApisixTlses returns a ApisixTlsInformer.
+func (v *version) ApisixTlses() ApisixTlsInformer {
+	return &apisixTlsInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
 }
 
 // ApisixUpstreams returns a ApisixUpstreamInformer.
diff --git a/pkg/kube/apisix/client/informers/externalversions/generic.go b/pkg/kube/apisix/client/informers/externalversions/generic.go
index 341c5be..b588a1f 100644
--- a/pkg/kube/apisix/client/informers/externalversions/generic.go
+++ b/pkg/kube/apisix/client/informers/externalversions/generic.go
@@ -57,8 +57,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1().ApisixRoutes().Informer()}, nil
 	case v1.SchemeGroupVersion.WithResource("apisixservices"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1().ApisixServices().Informer()}, nil
-	case v1.SchemeGroupVersion.WithResource("apisixtlss"):
-		return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1().ApisixTLSs().Informer()}, nil
+	case v1.SchemeGroupVersion.WithResource("apisixtlses"):
+		return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1().ApisixTlses().Informer()}, nil
 	case v1.SchemeGroupVersion.WithResource("apisixupstreams"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Apisix().V1().ApisixUpstreams().Informer()}, nil
 
diff --git a/pkg/kube/apisix/client/listers/config/v1/apisixtls.go b/pkg/kube/apisix/client/listers/config/v1/apisixtls.go
index 1033901..9061ab1 100644
--- a/pkg/kube/apisix/client/listers/config/v1/apisixtls.go
+++ b/pkg/kube/apisix/client/listers/config/v1/apisixtls.go
@@ -25,69 +25,69 @@ import (
 	"k8s.io/client-go/tools/cache"
 )
 
-// ApisixTLSLister helps list ApisixTLSs.
+// ApisixTlsLister helps list ApisixTlses.
 // All objects returned here must be treated as read-only.
-type ApisixTLSLister interface {
-	// List lists all ApisixTLSs in the indexer.
+type ApisixTlsLister interface {
+	// List lists all ApisixTlses in the indexer.
 	// Objects returned here must be treated as read-only.
-	List(selector labels.Selector) (ret []*v1.ApisixTLS, err error)
-	// ApisixTLSs returns an object that can list and get ApisixTLSs.
-	ApisixTLSs(namespace string) ApisixTLSNamespaceLister
-	ApisixTLSListerExpansion
+	List(selector labels.Selector) (ret []*v1.ApisixTls, err error)
+	// ApisixTlses returns an object that can list and get ApisixTlses.
+	ApisixTlses(namespace string) ApisixTlsNamespaceLister
+	ApisixTlsListerExpansion
 }
 
-// apisixTLSLister implements the ApisixTLSLister interface.
-type apisixTLSLister struct {
+// apisixTlsLister implements the ApisixTlsLister interface.
+type apisixTlsLister struct {
 	indexer cache.Indexer
 }
 
-// NewApisixTLSLister returns a new ApisixTLSLister.
-func NewApisixTLSLister(indexer cache.Indexer) ApisixTLSLister {
-	return &apisixTLSLister{indexer: indexer}
+// NewApisixTlsLister returns a new ApisixTlsLister.
+func NewApisixTlsLister(indexer cache.Indexer) ApisixTlsLister {
+	return &apisixTlsLister{indexer: indexer}
 }
 
-// List lists all ApisixTLSs in the indexer.
-func (s *apisixTLSLister) List(selector labels.Selector) (ret []*v1.ApisixTLS, err error) {
+// List lists all ApisixTlses in the indexer.
+func (s *apisixTlsLister) List(selector labels.Selector) (ret []*v1.ApisixTls, err error) {
 	err = cache.ListAll(s.indexer, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1.ApisixTLS))
+		ret = append(ret, m.(*v1.ApisixTls))
 	})
 	return ret, err
 }
 
-// ApisixTLSs returns an object that can list and get ApisixTLSs.
-func (s *apisixTLSLister) ApisixTLSs(namespace string) ApisixTLSNamespaceLister {
-	return apisixTLSNamespaceLister{indexer: s.indexer, namespace: namespace}
+// ApisixTlses returns an object that can list and get ApisixTlses.
+func (s *apisixTlsLister) ApisixTlses(namespace string) ApisixTlsNamespaceLister {
+	return apisixTlsNamespaceLister{indexer: s.indexer, namespace: namespace}
 }
 
-// ApisixTLSNamespaceLister helps list and get ApisixTLSs.
+// ApisixTlsNamespaceLister helps list and get ApisixTlses.
 // All objects returned here must be treated as read-only.
-type ApisixTLSNamespaceLister interface {
-	// List lists all ApisixTLSs in the indexer for a given namespace.
+type ApisixTlsNamespaceLister interface {
+	// List lists all ApisixTlses in the indexer for a given namespace.
 	// Objects returned here must be treated as read-only.
-	List(selector labels.Selector) (ret []*v1.ApisixTLS, err error)
-	// Get retrieves the ApisixTLS from the indexer for a given namespace and name.
+	List(selector labels.Selector) (ret []*v1.ApisixTls, err error)
+	// Get retrieves the ApisixTls from the indexer for a given namespace and name.
 	// Objects returned here must be treated as read-only.
-	Get(name string) (*v1.ApisixTLS, error)
-	ApisixTLSNamespaceListerExpansion
+	Get(name string) (*v1.ApisixTls, error)
+	ApisixTlsNamespaceListerExpansion
 }
 
-// apisixTLSNamespaceLister implements the ApisixTLSNamespaceLister
+// apisixTlsNamespaceLister implements the ApisixTlsNamespaceLister
 // interface.
-type apisixTLSNamespaceLister struct {
+type apisixTlsNamespaceLister struct {
 	indexer   cache.Indexer
 	namespace string
 }
 
-// List lists all ApisixTLSs in the indexer for a given namespace.
-func (s apisixTLSNamespaceLister) List(selector labels.Selector) (ret []*v1.ApisixTLS, err error) {
+// List lists all ApisixTlses in the indexer for a given namespace.
+func (s apisixTlsNamespaceLister) List(selector labels.Selector) (ret []*v1.ApisixTls, err error) {
 	err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1.ApisixTLS))
+		ret = append(ret, m.(*v1.ApisixTls))
 	})
 	return ret, err
 }
 
-// Get retrieves the ApisixTLS from the indexer for a given namespace and name.
-func (s apisixTLSNamespaceLister) Get(name string) (*v1.ApisixTLS, error) {
+// Get retrieves the ApisixTls from the indexer for a given namespace and name.
+func (s apisixTlsNamespaceLister) Get(name string) (*v1.ApisixTls, error) {
 	obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
 	if err != nil {
 		return nil, err
@@ -95,5 +95,5 @@ func (s apisixTLSNamespaceLister) Get(name string) (*v1.ApisixTLS, error) {
 	if !exists {
 		return nil, errors.NewNotFound(v1.Resource("apisixtls"), name)
 	}
-	return obj.(*v1.ApisixTLS), nil
+	return obj.(*v1.ApisixTls), nil
 }
diff --git a/pkg/kube/apisix/client/listers/config/v1/expansion_generated.go b/pkg/kube/apisix/client/listers/config/v1/expansion_generated.go
index 860dec9..be19d49 100644
--- a/pkg/kube/apisix/client/listers/config/v1/expansion_generated.go
+++ b/pkg/kube/apisix/client/listers/config/v1/expansion_generated.go
@@ -34,13 +34,13 @@ type ApisixServiceListerExpansion interface{}
 // ApisixServiceNamespaceLister.
 type ApisixServiceNamespaceListerExpansion interface{}
 
-// ApisixTLSListerExpansion allows custom methods to be added to
-// ApisixTLSLister.
-type ApisixTLSListerExpansion interface{}
+// ApisixTlsListerExpansion allows custom methods to be added to
+// ApisixTlsLister.
+type ApisixTlsListerExpansion interface{}
 
-// ApisixTLSNamespaceListerExpansion allows custom methods to be added to
-// ApisixTLSNamespaceLister.
-type ApisixTLSNamespaceListerExpansion interface{}
+// ApisixTlsNamespaceListerExpansion allows custom methods to be added to
+// ApisixTlsNamespaceLister.
+type ApisixTlsNamespaceListerExpansion interface{}
 
 // ApisixUpstreamListerExpansion allows custom methods to be added to
 // ApisixUpstreamLister.
diff --git a/pkg/types/apisix/v1/types.go b/pkg/types/apisix/v1/types.go
index 4354be4..a249ed2 100644
--- a/pkg/types/apisix/v1/types.go
+++ b/pkg/types/apisix/v1/types.go
@@ -120,10 +120,11 @@ type Node struct {
 // Ssl apisix ssl object
 // +k8s:deepcopy-gen=true
 type Ssl struct {
-	ID     string   `json:"id,omitempty" yaml:"id,omitempty"`
-	Snis   []string `json:"snis,omitempty" yaml:"snis,omitempty"`
-	Cert   string   `json:"cert,omitempty" yaml:"cert,omitempty"`
-	Key    string   `json:"key,omitempty" yaml:"key,omitempty"`
-	Status int      `json:"status,omitempty" yaml:"status,omitempty"`
-	Group  string   `json:"group,omitempty" yaml:"group,omitempty"`
+	ID       string   `json:"id,omitempty" yaml:"id,omitempty"`
+	FullName string   `json:"full_name,omitempty" yaml:"full_name,omitempty"`
+	Snis     []string `json:"snis,omitempty" yaml:"snis,omitempty"`
+	Cert     string   `json:"cert,omitempty" yaml:"cert,omitempty"`
+	Key      string   `json:"key,omitempty" yaml:"key,omitempty"`
+	Status   int      `json:"status,omitempty" yaml:"status,omitempty"`
+	Group    string   `json:"group,omitempty" yaml:"group,omitempty"`
 }
diff --git a/test/e2e/ingress/resourcepushing.go b/test/e2e/ingress/resourcepushing.go
index bd1b0e6..be24f97 100644
--- a/test/e2e/ingress/resourcepushing.go
+++ b/test/e2e/ingress/resourcepushing.go
@@ -16,6 +16,7 @@ package ingress
 
 import (
 	"fmt"
+	"net/http"
 	"time"
 
 	"github.com/onsi/ginkgo"
@@ -32,16 +33,16 @@ var _ = ginkgo.Describe("ApisixRoute Testing", func() {
 apiVersion: apisix.apache.org/v1
 kind: ApisixRoute
 metadata:
- name: httpbin-route
+  name: httpbin-route
 spec:
- rules:
- - host: httpbin.com
-   http:
-     paths:
-     - backend:
-         serviceName: %s
-         servicePort: %d
-       path: /ip
+  rules:
+  - host: httpbin.com
+    http:
+      paths:
+      - backend:
+          serviceName: %s
+          servicePort: %d
+        path: /ip
 `, backendSvc, backendSvcPort[0])
 		assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(apisixRoute))
 
@@ -53,10 +54,11 @@ spec:
 		assert.Nil(ginkgo.GinkgoT(), s.WaitAllHTTPBINPoddsAvailable(), "waiting for all httpbin pods ready")
 		// TODO When ingress controller can feedback the lifecycle of CRDs to the
 		// status field, we can poll it rather than sleeping.
-		time.Sleep(5 * time.Second)
+		time.Sleep(10 * time.Second)
 		ups, err := s.ListApisixUpstreams()
 		assert.Nil(ginkgo.GinkgoT(), err, "list upstreams error")
 		assert.Len(ginkgo.GinkgoT(), ups[0].Nodes, 2, "upstreams nodes not expect")
+		s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
 	})
 
 	ginkgo.It("create and then remove", func() {
diff --git a/test/e2e/ingress/ssl.go b/test/e2e/ingress/ssl.go
new file mode 100644
index 0000000..72d1d32
--- /dev/null
+++ b/test/e2e/ingress/ssl.go
@@ -0,0 +1,235 @@
+// 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 ingress
+
+import (
+	"time"
+
+	"github.com/onsi/ginkgo"
+	"github.com/stretchr/testify/assert"
+
+	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("SSL Testing", func() {
+	s := scaffold.NewDefaultScaffold()
+	ginkgo.It("create a SSL from ApisixTls ", func() {
+		secretName := "test-apisix-tls"
+		cert := `-----BEGIN CERTIFICATE-----
+MIIDSjCCAjICCQC/34ZwGz7ZXjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJD
+TjEQMA4GA1UECAwHSmlhbmdzdTEPMA0GA1UEBwwGU3V6aG91MQ8wDQYDVQQKDAZ6
+aGlsaXUxEDAOBgNVBAsMB3NlY3Rpb24xETAPBgNVBAMMCHRlc3QuY29tMCAXDTIx
+MDIwMzE0MjkwOVoYDzIwNTEwMTI3MTQyOTA5WjBmMQswCQYDVQQGEwJDTjEQMA4G
+A1UECAwHSmlhbmdzdTEPMA0GA1UEBwwGU3V6aG91MQ8wDQYDVQQKDAZ6aGlsaXUx
+EDAOBgNVBAsMB3NlY3Rpb24xETAPBgNVBAMMCHRlc3QuY29tMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3DEQ5K9PVYicINTHt3arqrsrftrhotyBuGqM
+xxqGMVO/E2SAa/81fC1UCcjYV4Wila0kl8i5fa8HjtVm5UWlrqxeFLOS3E0Wv2QY
+w46BGZJY4InE9zKwYyC2DkBxE6p14JRjmtW/MQPNaOFjJ4bmCuRHsEzmQIGRM0b7
+oKHjfFwv6l7BahgGf9ShHOMdHSkgWj6+2RU3282lrO9bY1JBTKu2Znv9M79nu1Px
+Tn1wCfcuCwA7WQT/QSrE2R43I2vmbIbuSmeg9ivjMazRYQQ+qxQn/6zhiHvP3QZG
+dKmp8imdYi+r84PKOLDEe/yxlgIdr2Au5WCPWwyYMYPWHzeD1wIDAQABMA0GCSqG
+SIb3DQEBCwUAA4IBAQBYzNe83mPVuz96TZ3fmxtOIuz9b6q5JWiJiOzjAD9902Se
+TNYzMM6T/5e0dBpj8Z2qQlhkfNxJJgTwGEE8SdrZIr8DhswR9a0bXDCZjLatCdeU
+iYpt+TDAuySnLhAcd3GfE5ml6am2dOsOKpxHU/8clUSaz+21fckRopWo+xL6rSVC
+4vvKqiU+LWLTZPQNoOqowl7bxoQO2jMWfN/5zvQOFxAbEufIPa9ti3qonDCXbkYn
+PpET/mPDrcb4bGsZkW/cu0LrPSUVp12br5TAYaXqYS0Ex+jAVTXML9SeEQuvU3dH
+5Uw2wVHxQXHglsdCYUXXFd3HZffb4rSQH+Mk0CBI
+-----END CERTIFICATE-----`
+		key := `-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA3DEQ5K9PVYicINTHt3arqrsrftrhotyBuGqMxxqGMVO/E2SA
+a/81fC1UCcjYV4Wila0kl8i5fa8HjtVm5UWlrqxeFLOS3E0Wv2QYw46BGZJY4InE
+9zKwYyC2DkBxE6p14JRjmtW/MQPNaOFjJ4bmCuRHsEzmQIGRM0b7oKHjfFwv6l7B
+ahgGf9ShHOMdHSkgWj6+2RU3282lrO9bY1JBTKu2Znv9M79nu1PxTn1wCfcuCwA7
+WQT/QSrE2R43I2vmbIbuSmeg9ivjMazRYQQ+qxQn/6zhiHvP3QZGdKmp8imdYi+r
+84PKOLDEe/yxlgIdr2Au5WCPWwyYMYPWHzeD1wIDAQABAoIBAQDGmSKpgE1H0k0v
+d3siyFART3vtkLHOWKBPmxqaQhwixWwjq5QA1FCDTcbshFBMsGVyJpZIqGxVJdbl
+RyjlRaooH6NDfKvLM2R+/2Mujot2av7qlpgmdXuODOTnecwDds2W33/vGTa2mL1e
+CVuLPSqjTD40j0dlivdRjoZJ3Xn2oOrpZ812XU8KeZAjuSEAwcyl2nSbyLGDchBB
+kfYZold3FaaLAf2LoVJ2fs+FwEPzDKoNYEvij9OyC0kwI94T5jQ+Z6XGtHXhb2Hy
+Ek3EZeIhV3YcDIid5AjSvcrNtDI24hwszSmhYVc53EKYkpXHf581a3U/SEEhXDlw
+Y0x6j9QRAoGBAPEP0LDgP7DGXxno4h+nf0AMru0pxlrNVQhLcNQB+dYI0pFTwsg+
+AKenoaaE/EGR1KfiY0uf3rVWNrA5kyX1/i18iJx9LSf9NvNgMo84JVvXINgyE6sd
+hvdqxFlV5FBnh8b7ldvYQy3YI0EQNx+/rmeUYPjInbkdiksAtAey4ADNAoGBAOnW
+K0FoX1ljq3rc9uVasiRi6Ix50NHdZ17RcEpMgwWPenbP1aiWkvA8yFhU708lBaZC
+WIUZ6XbfiG0Y9cMtxhtikoouDs5Ifia8juZ2bhkmSGP2FvZCBJJ/sHhnhpzSZNhW
+SyLBUjnynoXwHoQvkoGnVTHAk1VsY7jLNJdr2MczAoGAMYvMmu4caRr8pPimsVbd
+4q44reouKK+XUJMg55JYZVN+4/vRRxLnU44yvWUL6/YrPS5ctkhvn9nOd739rom2
+6mZ0NaXMyDFVQAR/n8wscYnv6D+ypzL0cJnzLWFoAdalo5JGJN94P03zQQYyLkZZ
+dFSc8cVaFZgqumu0lPiA7ekCgYEAiMeVL8Jcm84YXVrpNMmzkGMmwhzzT/8hWy5J
+b7yHm3YM3Xi+8sl5E/uJ+VldTj9KqbD/VIQOs1EX3TEPeObKjfQ/4YIFeRagbAo5
+0IcP6bgh+g7V6aA+Sm9Ui2mLLSpIgN8hPig0796CabhGMW4eVabKx7pstDgdsNd0
+YOpduE8CgYEAu9k9WOQuRX4f6i5LBIxyaYn6Hw6oJn8e/w+p2+HNBXdyVQNqUHBG
+V5rgnBwhc5LeIFbehKvQOvYSWbwbA1VunMpdYgV6+EBLayumJNqV6jGei4okx2of
+wrw7im4TNSAdwVX4Y1F4svJ2as5SJn5QYGAzXDixNuwzXYrpP9rzA2s=
+-----END RSA PRIVATE KEY-----`
+		// create secret
+		err := s.NewSecret(secretName, cert, key)
+		assert.Nil(ginkgo.GinkgoT(), err, "create secret error")
+		// create ApisixTls resource
+		tlsName := "tls-name"
+		host := "api6.com"
+		err = s.NewApisixTls(tlsName, host, secretName)
+		assert.Nil(ginkgo.GinkgoT(), err, "create tls error")
+		// check ssl in APISIX
+		time.Sleep(10 * time.Second)
+		tls, err := s.ListApisixTls()
+		assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
+		assert.Len(ginkgo.GinkgoT(), tls, 1, "tls number not expect")
+	})
+	ginkgo.It("update a SSL from ApisixTls ", func() {
+		secretName := "test-apisix-tls"
+		cert := `-----BEGIN CERTIFICATE-----
+MIIDSDCCAjACCQDf02nwtW2VrzANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJj
+bjEQMA4GA1UECAwHamlhbmdzdTEPMA0GA1UEBwwGc3V6aG91MQ8wDQYDVQQKDAZ6
+aGlsaXUxEDAOBgNVBAsMB3NlY3Rpb24xETAPBgNVBAMMCGFwaTYuY29tMB4XDTIx
+MDEyNTA2MDQ0MVoXDTIxMDIyNDA2MDQ0MVowZjELMAkGA1UEBhMCY24xEDAOBgNV
+BAgMB2ppYW5nc3UxDzANBgNVBAcMBnN1emhvdTEPMA0GA1UECgwGemhpbGl1MRAw
+DgYDVQQLDAdzZWN0aW9uMREwDwYDVQQDDAhhcGk2LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAMQFzmobVVuixOa0cEItZLzt3gKifUS1b+sN5d0y
+7SGKeApjhgSl0bl1xFXEGyFttCNlFU0+adbKHXJLsNFbO/l8xi+218ihYZ1mM708
+8T8IJM4d4jpx0OKFZSU9two+VxNLTwFsat2GiB39KMiNpLOShhIdK9BKT8+v6Uqq
+MbkYoCCRObcBsCuA7hhyteSdN7ccuxuMS28862R4gvhXGF2+BBXLnegzHE3PKexF
+0vekJcfVH/LKS0iwl+Gcn6isJXQQTx6+llko+Flh7fqbrDIKV4EJm/5GfULJkjlp
+SviTHJ5rJgZUjdkozA2O8ELpb3vsjEs44M+3h6v+AQ8LSrkCAwEAATANBgkqhkiG
+9w0BAQsFAAOCAQEABt98FafJfmZ2Gaf/Fip9bf4qxGUlRfJpZ8K775VRSXAcI/by
+Bh4wjd3DwUMVFFarx8CxcGHgjpK6bWE3tkQjc7R24xhPVaF/zyiPakrTHkWENHPZ
+HbkOmZOY8wfZ8pPGUwHGA6bCmytWSD0lseEhxaHcZ27MmKI5CdUsgJXbc1q9gr3F
+x4cosJI+W55Kzejiqgm/wzBbr4OpjW4DDz1YBJFXCc1TN9pf2ALkWZ8j3HfMrn2y
+HvOefA8g628WpNtPZodWe/zC8hanCzRMp37JPbh85+RwlGhi7gIkhvjf78EiAZBy
+eHg1iDgdVUzlXn+LNPCAbjxCaTqn6zmIb+GkhA==
+-----END CERTIFICATE-----`
+		key := `-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAxAXOahtVW6LE5rRwQi1kvO3eAqJ9RLVv6w3l3TLtIYp4CmOG
+BKXRuXXEVcQbIW20I2UVTT5p1sodckuw0Vs7+XzGL7bXyKFhnWYzvTzxPwgkzh3i
+OnHQ4oVlJT23Cj5XE0tPAWxq3YaIHf0oyI2ks5KGEh0r0EpPz6/pSqoxuRigIJE5
+twGwK4DuGHK15J03txy7G4xLbzzrZHiC+FcYXb4EFcud6DMcTc8p7EXS96Qlx9Uf
+8spLSLCX4ZyfqKwldBBPHr6WWSj4WWHt+pusMgpXgQmb/kZ9QsmSOWlK+JMcnmsm
+BlSN2SjMDY7wQulve+yMSzjgz7eHq/4BDwtKuQIDAQABAoIBAQCfVbTmDNfCR7lT
+agIB2NIUvCkE7T1z1yNk5gQdXCLia6KNlz49kue5n596s4/2CS0uxCCfjAcN/3YW
+DK5qToWekyypZi9aNsuY3JVb0iiqupzoKeRU62UGa7W+or6hBfFTjphmqNDoxkzo
+S3qWIoRpLsXp/Wo6wdzEDdJMzbDjKVHUdcoeJ2IQdMG4dKKdf9NMZOhohZs+K0Kf
+oroLTbrjCf5wI16KPxHVKe/6vw3098GKJc+MTfHtANJbwmI4dAlLcfbZ1I6VUoL6
+JkCphK8BJ2jxeu0xTu7TXkHcMd/yK4pKmEQwjSpDOl0qWgFYAXJR2RHCaduR6w4l
+XJcbnARtAoGBAPmwYjGHeCpzQdHA6Atkc9ETSdzfRShG7H/cRdluS6J4KEAJAFW7
+i+Xc3rQf67CR/3JJgXObL1ZvQeIZ0Q0UD0WbBopJc2hfGRKN9lsFclMqDTzBHvvi
+ZukE/IvL3elhtuskLyc9Wf0JGoEsdkQkMQT+wMyxbrZ6im2MWm/xswrnAoGBAMj6
+LIysCK2LbOcPoi33nOGBC2ITUwhJGbbCeBho0xqpzcD20aQszJmYJkDng2WVkjdf
+3MO2HDULA2JvEMdCrjvG5U1smLdbBQ89aIhy6clDKb5PMlOo9fo3E9ICyL5StFyy
+09H0UGoCocZlBPOZQ70k5kLYOKf7QB9TeTyaIulfAoGAHDww7m7mTM6Zy9FnrBog
+6qymtp5c4LAcgFz1XSAW13mE+7DI4+kAae7vFClj6qSn4VGknOEYmkqchafrtvHk
+xDdCpxKlRVEzsaByElrsUbE4q/0ettckUgdpU5mrL4AIQlDmMCbE7VNBNwhDG3OI
+Q4tXXA5YebQjwT2U4IHRgFMCgYEAxc82Od65S9aHAYUpowSrrGhOw+ExQF5yqKcP
+fTbvULcAhIRqIqTVW/ec7xTvBvUITOhVaWu8p5iHZELcyMKgqsVAu8u/I/i6Kh3O
+3T39TNKGK4HXjvAl6nh7UaDb5DeSvgpk4akN3MlqYNLc5MZdHbVLzU7ztKJeonaO
+RU+QPRECgYB6XW24EI5+w3STbpnc6VoTS+sy9I9abTJPYo9LpCJwfMYc9Tg9Cx2K
+29PnmSrLFpU2fvE0ijpyHRr7gGmINTxbrmTmfMBI01m+GpPuvDcBQ2tsFJ+A3DzN
+9xJulR2NZUZdDIIIqx983ANE6S4Zb8rAbsoHQdqpjUrcVxI2OJBp3Q==
+-----END RSA PRIVATE KEY-----`
+		// create secret
+		err := s.NewSecret(secretName, cert, key)
+		assert.Nil(ginkgo.GinkgoT(), err, "create secret error")
+		// create ApisixTls resource
+		tlsName := "tls-name"
+		host := "api6.com"
+		err = s.NewApisixTls(tlsName, host, secretName)
+		assert.Nil(ginkgo.GinkgoT(), err, "create tls error")
+		// update ApisixTls resource
+		host = "api7.com"
+		err = s.NewApisixTls(tlsName, host, secretName)
+		assert.Nil(ginkgo.GinkgoT(), err, "update tls error")
+
+		// check ssl in APISIX
+		time.Sleep(10 * time.Second)
+		tls, err := s.ListApisixTls()
+		assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
+		assert.Len(ginkgo.GinkgoT(), tls, 1, "tls number not expect")
+		assert.Equal(ginkgo.GinkgoT(), tls[0].Snis[0], host, "tls host is error")
+	})
+	ginkgo.It("delete a SSL from ApisixTls ", func() {
+		secretName := "test-apisix-tls"
+		cert := `-----BEGIN CERTIFICATE-----
+MIIDSDCCAjACCQDf02nwtW2VrzANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJj
+bjEQMA4GA1UECAwHamlhbmdzdTEPMA0GA1UEBwwGc3V6aG91MQ8wDQYDVQQKDAZ6
+aGlsaXUxEDAOBgNVBAsMB3NlY3Rpb24xETAPBgNVBAMMCGFwaTYuY29tMB4XDTIx
+MDEyNTA2MDQ0MVoXDTIxMDIyNDA2MDQ0MVowZjELMAkGA1UEBhMCY24xEDAOBgNV
+BAgMB2ppYW5nc3UxDzANBgNVBAcMBnN1emhvdTEPMA0GA1UECgwGemhpbGl1MRAw
+DgYDVQQLDAdzZWN0aW9uMREwDwYDVQQDDAhhcGk2LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAMQFzmobVVuixOa0cEItZLzt3gKifUS1b+sN5d0y
+7SGKeApjhgSl0bl1xFXEGyFttCNlFU0+adbKHXJLsNFbO/l8xi+218ihYZ1mM708
+8T8IJM4d4jpx0OKFZSU9two+VxNLTwFsat2GiB39KMiNpLOShhIdK9BKT8+v6Uqq
+MbkYoCCRObcBsCuA7hhyteSdN7ccuxuMS28862R4gvhXGF2+BBXLnegzHE3PKexF
+0vekJcfVH/LKS0iwl+Gcn6isJXQQTx6+llko+Flh7fqbrDIKV4EJm/5GfULJkjlp
+SviTHJ5rJgZUjdkozA2O8ELpb3vsjEs44M+3h6v+AQ8LSrkCAwEAATANBgkqhkiG
+9w0BAQsFAAOCAQEABt98FafJfmZ2Gaf/Fip9bf4qxGUlRfJpZ8K775VRSXAcI/by
+Bh4wjd3DwUMVFFarx8CxcGHgjpK6bWE3tkQjc7R24xhPVaF/zyiPakrTHkWENHPZ
+HbkOmZOY8wfZ8pPGUwHGA6bCmytWSD0lseEhxaHcZ27MmKI5CdUsgJXbc1q9gr3F
+x4cosJI+W55Kzejiqgm/wzBbr4OpjW4DDz1YBJFXCc1TN9pf2ALkWZ8j3HfMrn2y
+HvOefA8g628WpNtPZodWe/zC8hanCzRMp37JPbh85+RwlGhi7gIkhvjf78EiAZBy
+eHg1iDgdVUzlXn+LNPCAbjxCaTqn6zmIb+GkhA==
+-----END CERTIFICATE-----`
+		key := `-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAxAXOahtVW6LE5rRwQi1kvO3eAqJ9RLVv6w3l3TLtIYp4CmOG
+BKXRuXXEVcQbIW20I2UVTT5p1sodckuw0Vs7+XzGL7bXyKFhnWYzvTzxPwgkzh3i
+OnHQ4oVlJT23Cj5XE0tPAWxq3YaIHf0oyI2ks5KGEh0r0EpPz6/pSqoxuRigIJE5
+twGwK4DuGHK15J03txy7G4xLbzzrZHiC+FcYXb4EFcud6DMcTc8p7EXS96Qlx9Uf
+8spLSLCX4ZyfqKwldBBPHr6WWSj4WWHt+pusMgpXgQmb/kZ9QsmSOWlK+JMcnmsm
+BlSN2SjMDY7wQulve+yMSzjgz7eHq/4BDwtKuQIDAQABAoIBAQCfVbTmDNfCR7lT
+agIB2NIUvCkE7T1z1yNk5gQdXCLia6KNlz49kue5n596s4/2CS0uxCCfjAcN/3YW
+DK5qToWekyypZi9aNsuY3JVb0iiqupzoKeRU62UGa7W+or6hBfFTjphmqNDoxkzo
+S3qWIoRpLsXp/Wo6wdzEDdJMzbDjKVHUdcoeJ2IQdMG4dKKdf9NMZOhohZs+K0Kf
+oroLTbrjCf5wI16KPxHVKe/6vw3098GKJc+MTfHtANJbwmI4dAlLcfbZ1I6VUoL6
+JkCphK8BJ2jxeu0xTu7TXkHcMd/yK4pKmEQwjSpDOl0qWgFYAXJR2RHCaduR6w4l
+XJcbnARtAoGBAPmwYjGHeCpzQdHA6Atkc9ETSdzfRShG7H/cRdluS6J4KEAJAFW7
+i+Xc3rQf67CR/3JJgXObL1ZvQeIZ0Q0UD0WbBopJc2hfGRKN9lsFclMqDTzBHvvi
+ZukE/IvL3elhtuskLyc9Wf0JGoEsdkQkMQT+wMyxbrZ6im2MWm/xswrnAoGBAMj6
+LIysCK2LbOcPoi33nOGBC2ITUwhJGbbCeBho0xqpzcD20aQszJmYJkDng2WVkjdf
+3MO2HDULA2JvEMdCrjvG5U1smLdbBQ89aIhy6clDKb5PMlOo9fo3E9ICyL5StFyy
+09H0UGoCocZlBPOZQ70k5kLYOKf7QB9TeTyaIulfAoGAHDww7m7mTM6Zy9FnrBog
+6qymtp5c4LAcgFz1XSAW13mE+7DI4+kAae7vFClj6qSn4VGknOEYmkqchafrtvHk
+xDdCpxKlRVEzsaByElrsUbE4q/0ettckUgdpU5mrL4AIQlDmMCbE7VNBNwhDG3OI
+Q4tXXA5YebQjwT2U4IHRgFMCgYEAxc82Od65S9aHAYUpowSrrGhOw+ExQF5yqKcP
+fTbvULcAhIRqIqTVW/ec7xTvBvUITOhVaWu8p5iHZELcyMKgqsVAu8u/I/i6Kh3O
+3T39TNKGK4HXjvAl6nh7UaDb5DeSvgpk4akN3MlqYNLc5MZdHbVLzU7ztKJeonaO
+RU+QPRECgYB6XW24EI5+w3STbpnc6VoTS+sy9I9abTJPYo9LpCJwfMYc9Tg9Cx2K
+29PnmSrLFpU2fvE0ijpyHRr7gGmINTxbrmTmfMBI01m+GpPuvDcBQ2tsFJ+A3DzN
+9xJulR2NZUZdDIIIqx983ANE6S4Zb8rAbsoHQdqpjUrcVxI2OJBp3Q==
+-----END RSA PRIVATE KEY-----`
+		// create secret
+		err := s.NewSecret(secretName, cert, key)
+		assert.Nil(ginkgo.GinkgoT(), err, "create secret error")
+		// create ApisixTls resource
+		tlsName := "tls-name"
+		host := "api6.com"
+		err = s.NewApisixTls(tlsName, host, secretName)
+		assert.Nil(ginkgo.GinkgoT(), err, "create tls error")
+
+		// check ssl in APISIX
+		time.Sleep(10 * time.Second)
+		tls, err := s.ListApisixTls()
+		assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
+		assert.Len(ginkgo.GinkgoT(), tls, 1, "tls number not expect")
+		assert.Equal(ginkgo.GinkgoT(), tls[0].Snis[0], host, "tls host is error")
+
+		// delete ApisixTls
+		err = s.DeleteApisixTls(tlsName, host, secretName)
+		assert.Nil(ginkgo.GinkgoT(), err, "delete tls error")
+		// check ssl in APISIX
+		time.Sleep(10 * time.Second)
+		tls, err = s.ListApisixTls()
+		assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
+		assert.Len(ginkgo.GinkgoT(), tls, 0, "tls number not expect")
+	})
+})
diff --git a/test/e2e/scaffold/apisix.go b/test/e2e/scaffold/apisix.go
index 7915af2..f4448fe 100644
--- a/test/e2e/scaffold/apisix.go
+++ b/test/e2e/scaffold/apisix.go
@@ -87,6 +87,9 @@ spec:
             - containerPort: 9180
               name: "http-admin"
               protocol: "TCP"
+            - containerPort: 9443
+              name: "https"
+              protocol: "TCP"
           volumeMounts:
             - mountPath: /usr/local/apisix/conf/config.yaml
               name: apisix-config-yaml-configmap
@@ -116,6 +119,10 @@ spec:
       port: 9180
       protocol: TCP
       targetPort: 9180
+    - name: https
+      port: 9443
+      protocol: TCP
+      targetPort: 9443
   type: NodePort
 `
 )
@@ -139,6 +146,25 @@ func (s *Scaffold) apisixServiceURL() (string, error) {
 	return "", errors.New("no http port in apisix service")
 }
 
+func (s *Scaffold) apisixServiceHttpsURL() (string, error) {
+	if len(s.nodes) == 0 {
+		return "", errors.New("no available node")
+	}
+	var addr string
+	for _, node := range s.nodes {
+		if len(node.Status.Addresses) > 0 {
+			addr = node.Status.Addresses[0].Address
+			break
+		}
+	}
+	for _, port := range s.apisixService.Spec.Ports {
+		if port.Name == "https" {
+			return net.JoinHostPort(addr, strconv.Itoa(int(port.NodePort))), nil
+		}
+	}
+	return "", errors.New("no https port defined in apisix service")
+}
+
 func (s *Scaffold) apisixAdminServiceURL() (string, error) {
 	if len(s.nodes) == 0 {
 		return "", errors.New("no available node")
diff --git a/test/e2e/scaffold/crd.go b/test/e2e/scaffold/crd.go
index cb0ece0..9c8761c 100644
--- a/test/e2e/scaffold/crd.go
+++ b/test/e2e/scaffold/crd.go
@@ -204,3 +204,27 @@ func (s *Scaffold) ListApisixUpstreams() ([]*v1.Upstream, error) {
 	}
 	return cli.Cluster("").Upstream().List(context.TODO())
 }
+
+// ListApisixTls list all ssl from APISIX
+func (s *Scaffold) ListApisixTls() ([]*v1.Ssl, error) {
+	host, err := s.apisixAdminServiceURL()
+	if err != nil {
+		return nil, err
+	}
+	u := url.URL{
+		Scheme: "http",
+		Host:   host,
+		Path:   "/apisix/admin",
+	}
+	cli, err := apisix.NewClient()
+	if err != nil {
+		return nil, err
+	}
+	err = cli.AddCluster(&apisix.ClusterOptions{
+		BaseURL: u.String(),
+	})
+	if err != nil {
+		return nil, err
+	}
+	return cli.Cluster("").SSL().List(context.TODO())
+}
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index 18bee6d..acaf19c 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -16,6 +16,7 @@ package scaffold
 
 import (
 	"context"
+	"crypto/tls"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -27,8 +28,6 @@ import (
 	"text/template"
 	"time"
 
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
 	"github.com/gavv/httpexpect/v2"
 	"github.com/gruntwork-io/terratest/modules/k8s"
 	"github.com/gruntwork-io/terratest/modules/testing"
@@ -36,6 +35,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/wait"
 )
 
@@ -153,6 +153,30 @@ func (s *Scaffold) NewAPISIXClient() *httpexpect.Expect {
 	})
 }
 
+// NewAPISIXHttpsClient creates the default HTTPs client.
+func (s *Scaffold) NewAPISIXHttpsClient() *httpexpect.Expect {
+	host, err := s.apisixServiceHttpsURL()
+	assert.Nil(s.t, err, "getting apisix service url")
+	u := url.URL{
+		Scheme: "https",
+		Host:   host,
+	}
+	return httpexpect.WithConfig(httpexpect.Config{
+		BaseURL: u.String(),
+		Client: &http.Client{
+			Transport: &http.Transport{
+				TLSClientConfig: &tls.Config{
+					// accept any certificate; for testing only!
+					InsecureSkipVerify: true,
+				},
+			},
+		},
+		Reporter: httpexpect.NewAssertReporter(
+			httpexpect.NewAssertReporter(ginkgo.GinkgoT()),
+		),
+	})
+}
+
 func (s *Scaffold) beforeEach() {
 	var err error
 	s.namespace = fmt.Sprintf("ingress-apisix-e2e-tests-%s-%d", s.opts.Name, time.Now().Nanosecond())
diff --git a/test/e2e/scaffold/ssl.go b/test/e2e/scaffold/ssl.go
new file mode 100644
index 0000000..cdde5ab
--- /dev/null
+++ b/test/e2e/scaffold/ssl.go
@@ -0,0 +1,76 @@
+// 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 scaffold
+
+import (
+	"encoding/base64"
+	"fmt"
+
+	"github.com/gruntwork-io/terratest/modules/k8s"
+)
+
+const (
+	_secretTemplate = `
+apiVersion: v1
+kind: Secret
+metadata:
+  name: %s
+data:
+  cert: %s
+  key: %s
+`
+	_api6tlsTemplate = `
+apiVersion: apisix.apache.org/v1
+kind: ApisixTls
+metadata:
+  name: %s
+spec:
+  hosts:
+  - %s
+  secret:
+    name: %s
+    namespace: %s
+`
+)
+
+// NewSecret new a k8s secret
+func (s *Scaffold) NewSecret(name, cert, key string) error {
+	certBase64 := base64.StdEncoding.EncodeToString([]byte(cert))
+	keyBase64 := base64.StdEncoding.EncodeToString([]byte(key))
+	secret := fmt.Sprintf(_secretTemplate, name, certBase64, keyBase64)
+	if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, secret); err != nil {
+		return err
+	}
+	return nil
+}
+
+// NewApisixTls new a ApisixTls CRD
+func (s *Scaffold) NewApisixTls(name, host, secretName string) error {
+	tls := fmt.Sprintf(_api6tlsTemplate, name, host, secretName, s.kubectlOptions.Namespace)
+	if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, tls); err != nil {
+		return err
+	}
+	return nil
+}
+
+// DeleteApisixTls remove ApisixTls CRD
+func (s *Scaffold) DeleteApisixTls(name string, host, secretName string) error {
+	tls := fmt.Sprintf(_api6tlsTemplate, name, host, secretName, s.kubectlOptions.Namespace)
+	if err := k8s.KubectlDeleteFromStringE(s.t, s.kubectlOptions, tls); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/test/e2e/testdata/apisix-gw-config.yaml b/test/e2e/testdata/apisix-gw-config.yaml
index 8124b17..4fbcd17 100644
--- a/test/e2e/testdata/apisix-gw-config.yaml
+++ b/test/e2e/testdata/apisix-gw-config.yaml
@@ -66,7 +66,7 @@ apisix:
   dns_resolver_valid: 30          # valid time for dns result 30 seconds
   resolver_timeout: 5             # resolver timeout
   ssl:
-    enable: false
+    enable: true
     enable_http2: true
     listen_port: 9443
     ssl_protocols: "TLSv1.2 TLSv1.3"