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 2dd7f14  chore: controller tree (#361)
2dd7f14 is described below

commit 2dd7f143343410a610d7dd2fcf1cdd08f0131611
Author: Alex Zhang <zchao1...@gmail.com>
AuthorDate: Tue Apr 13 11:16:23 2021 +0800

    chore: controller tree (#361)
---
 .github/workflows/e2e-test-ci.yml               |   2 +-
 cmd/ingress/ingress.go                          |   2 +-
 pkg/apisix/ssl.go                               |   1 +
 pkg/ingress/apisix/tls.go                       |  66 ------
 pkg/ingress/apisix/tls_test.go                  | 133 -------------
 pkg/ingress/{controller => }/apisix_route.go    |   2 +-
 pkg/ingress/apisix_tls.go                       | 240 ++++++++++++++++++++++
 pkg/ingress/{controller => }/apisix_upstream.go |   2 +-
 pkg/ingress/{controller => }/controller.go      |  82 ++++----
 pkg/ingress/controller/apisix_tls.go            | 254 ------------------------
 pkg/ingress/{controller => }/endpoint.go        |   2 +-
 pkg/ingress/{controller => }/ingress.go         |   2 +-
 pkg/ingress/{controller => }/ingress_test.go    |   2 +-
 pkg/ingress/{controller => }/manifest.go        |   2 +-
 pkg/ingress/{controller => }/manifest_test.go   |   2 +-
 pkg/ingress/{controller => }/secret.go          | 116 ++++++-----
 pkg/ingress/{controller => }/types.go           |   2 +-
 pkg/kube/translation/apisix_ssl.go              |  58 ++++++
 pkg/kube/translation/translator.go              |   3 +
 pkg/seven/apisix/event.go                       |  23 ---
 pkg/seven/conf/conf.go                          |  50 -----
 pkg/seven/conf/conf_test.go                     |  24 ---
 pkg/seven/state/event.go                        |  21 --
 pkg/seven/state/solver.go                       |  46 -----
 pkg/seven/utils/diff.go                         |  59 ------
 pkg/seven/utils/http.go                         |  88 --------
 pkg/seven/utils/types.go                        |  20 --
 test/e2e/ingress/secret.go                      |   4 +-
 28 files changed, 423 insertions(+), 885 deletions(-)

diff --git a/.github/workflows/e2e-test-ci.yml 
b/.github/workflows/e2e-test-ci.yml
index d6f093e..6faafea 100644
--- a/.github/workflows/e2e-test-ci.yml
+++ b/.github/workflows/e2e-test-ci.yml
@@ -28,7 +28,7 @@ jobs:
       - name: Run e2e test cases
         working-directory: ./
         run: |
-          make e2e-test E2E_CONCURRENCY=2
+          make e2e-test E2E_CONCURRENCY=1
       - name: upload coverage profile
         working-directory: ./test/e2e
         run: |
diff --git a/cmd/ingress/ingress.go b/cmd/ingress/ingress.go
index c2a4b3a..f90b50f 100644
--- a/cmd/ingress/ingress.go
+++ b/cmd/ingress/ingress.go
@@ -26,7 +26,7 @@ import (
        "github.com/spf13/cobra"
 
        "github.com/apache/apisix-ingress-controller/pkg/config"
-       "github.com/apache/apisix-ingress-controller/pkg/ingress/controller"
+       controller "github.com/apache/apisix-ingress-controller/pkg/ingress"
        "github.com/apache/apisix-ingress-controller/pkg/log"
        "github.com/apache/apisix-ingress-controller/pkg/version"
 )
diff --git a/pkg/apisix/ssl.go b/pkg/apisix/ssl.go
index 684479a..7069c48 100644
--- a/pkg/apisix/ssl.go
+++ b/pkg/apisix/ssl.go
@@ -144,6 +144,7 @@ func (s *sslClient) Create(ctx context.Context, obj 
*v1.Ssl) (*v1.Ssl, error) {
                return nil, err
        }
        data, err := json.Marshal(v1.Ssl{
+               ID:     obj.ID,
                Snis:   obj.Snis,
                Cert:   obj.Cert,
                Key:    obj.Key,
diff --git a/pkg/ingress/apisix/tls.go b/pkg/ingress/apisix/tls.go
deleted file mode 100644
index 7ef31fa..0000000
--- a/pkg/ingress/apisix/tls.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 apisix
-
-import (
-       "context"
-
-       v1 "k8s.io/api/core/v1"
-       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
-       ingressConf "github.com/apache/apisix-ingress-controller/pkg/kube"
-       configv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1"
-       apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-type ApisixTLSCRD configv1.ApisixTls
-
-// Convert convert to  apisix.Ssl from ingress.ApisixTls CRD
-func (as *ApisixTLSCRD) Convert(sc Secreter) (*apisix.Ssl, error) {
-       name := as.Name
-       namespace := as.Namespace
-
-       id := namespace + "_" + name
-       secretName := as.Spec.Secret.Name
-       secretNamespace := as.Spec.Secret.Namespace
-       secret, err := sc.FindByName(secretNamespace, secretName)
-       if err != nil {
-               return nil, err
-       }
-       cert := string(secret.Data["cert"])
-       key := string(secret.Data["key"])
-       status := 1
-       var snis []string
-       snis = append(snis, as.Spec.Hosts...)
-       ssl := &apisix.Ssl{
-               ID:     id,
-               Snis:   snis,
-               Cert:   cert,
-               Key:    key,
-               Status: status,
-       }
-       return ssl, nil
-}
-
-type Secreter interface {
-       FindByName(namespace, name string) (*v1.Secret, error)
-}
-
-type SecretClient struct{}
-
-func (sc *SecretClient) FindByName(namespace, name string) (*v1.Secret, error) 
{
-       clientSet := ingressConf.GetKubeClient()
-       return clientSet.CoreV1().Secrets(namespace).Get(context.TODO(), name, 
metav1.GetOptions{})
-}
diff --git a/pkg/ingress/apisix/tls_test.go b/pkg/ingress/apisix/tls_test.go
deleted file mode 100644
index 4f5a3a1..0000000
--- a/pkg/ingress/apisix/tls_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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 apisix
-
-import (
-       "encoding/json"
-       "testing"
-
-       "github.com/stretchr/testify/assert"
-       "gopkg.in/yaml.v2"
-       v1 "k8s.io/api/core/v1"
-
-       apisixhttp "github.com/apache/apisix-ingress-controller/pkg/apisix"
-       "github.com/apache/apisix-ingress-controller/pkg/seven/conf"
-       "github.com/apache/apisix-ingress-controller/pkg/seven/utils"
-       apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-func TestConvert(t *testing.T) {
-       atlsStr := `
-apiVersion: apisix.apache.org/v1
-kind: ApisixTls
-metadata:
-  name: foo
-  namespace: helm
-spec:
-  hosts:
-  - api6.com
-  secret:
-    name: test-atls
-    namespace: helm
-`
-       id := "helm_foo"
-       snis := []string{"api6.com"}
-       status := 1
-       cert := "root"
-       key := "123456"
-       group := ""
-       sslExpect := &apisix.Ssl{
-               ID:     id,
-               Snis:   snis,
-               Cert:   cert,
-               Key:    key,
-               Status: status,
-               Group:  group,
-       }
-       atlsCRD := &ApisixTLSCRD{}
-       err := yaml.Unmarshal([]byte(atlsStr), atlsCRD)
-       assert.Nil(t, err, "yaml decode failed")
-       sc := &SecretClientMock{}
-       ssl, err := atlsCRD.Convert(sc)
-       assert.Nil(t, err)
-       assert.EqualValues(t, sslExpect.Key, ssl.Key, "key convert error")
-       assert.EqualValues(t, sslExpect.ID, ssl.ID, "id convert error")
-       assert.EqualValues(t, sslExpect.Cert, ssl.Cert, "cert convert error")
-       assert.EqualValues(t, sslExpect.Snis, ssl.Snis, "snis convert error")
-       assert.EqualValues(t, sslExpect.Group, ssl.Group, "group convert error")
-}
-
-func TestConvert_Error(t *testing.T) {
-       atlsStr := `
-apiVersion: apisix.apache.org/v1
-kind: ApisixTls
-metadata:
-  name: foo
-  namespace: helm
-spec:
-  secret:
-    name: test-atls
-    namespace: helm
-`
-       setDummyApisixClient(t)
-       atlsCRD := &ApisixTLSCRD{}
-       err := yaml.Unmarshal([]byte(atlsStr), atlsCRD)
-       assert.Nil(t, err, "yaml decode failed")
-       sc := &SecretClientErrorMock{}
-       ssl, err := atlsCRD.Convert(sc)
-       assert.Nil(t, ssl)
-       assert.NotNil(t, err)
-}
-
-type SecretClientMock struct{}
-
-func (sc *SecretClientMock) FindByName(namespace, name string) (*v1.Secret, 
error) {
-       secretStr := `
-{
-  "apiVersion": "v1",
-  "kind": "Secret",
-  "metadata": {
-    "name": "test-atls",
-    "namespace": "helm"
-  },
-  "data": {
-    "cert": "cm9vdA==",
-    "key": "MTIzNDU2"
-  }
-}
-`
-       secret := &v1.Secret{}
-       if err := json.Unmarshal([]byte(secretStr), secret); err != nil {
-               return nil, err
-       }
-       return secret, nil
-}
-
-type SecretClientErrorMock struct{}
-
-func (sc *SecretClientErrorMock) FindByName(namespace, name string) 
(*v1.Secret, error) {
-       return nil, utils.ErrNotFound
-}
-
-func setDummyApisixClient(t *testing.T) {
-       cli, err := apisixhttp.NewClient()
-       assert.Nil(t, err)
-       err = cli.AddCluster(&apisixhttp.ClusterOptions{
-               Name:    "",
-               BaseURL: "http://127.0.0.2:9080/apisix/admin";,
-       })
-       assert.Nil(t, err)
-       conf.SetAPISIXClient(cli)
-}
diff --git a/pkg/ingress/controller/apisix_route.go 
b/pkg/ingress/apisix_route.go
similarity index 99%
rename from pkg/ingress/controller/apisix_route.go
rename to pkg/ingress/apisix_route.go
index 36aded8..fd4ad5a 100644
--- a/pkg/ingress/controller/apisix_route.go
+++ b/pkg/ingress/apisix_route.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
diff --git a/pkg/ingress/apisix_tls.go b/pkg/ingress/apisix_tls.go
new file mode 100644
index 0000000..4e439df
--- /dev/null
+++ b/pkg/ingress/apisix_tls.go
@@ -0,0 +1,240 @@
+// 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 (
+       "context"
+       "sync"
+       "time"
+
+       "go.uber.org/zap"
+       k8serrors "k8s.io/apimachinery/pkg/api/errors"
+       "k8s.io/client-go/tools/cache"
+       "k8s.io/client-go/util/workqueue"
+
+       configv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1"
+       "github.com/apache/apisix-ingress-controller/pkg/log"
+       "github.com/apache/apisix-ingress-controller/pkg/types"
+       v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+)
+
+type apisixTlsController struct {
+       controller *Controller
+       workqueue  workqueue.RateLimitingInterface
+       workers    int
+}
+
+func (c *Controller) newApisixTlsController() *apisixTlsController {
+       ctl := &apisixTlsController{
+               controller: c,
+               workqueue:  
workqueue.NewNamedRateLimitingQueue(workqueue.NewItemFastSlowRateLimiter(1*time.Second,
 60*time.Second, 5), "ApisixTls"),
+               workers:    1,
+       }
+
+       ctl.controller.apisixTlsInformer.AddEventHandler(
+               cache.ResourceEventHandlerFuncs{
+                       AddFunc:    ctl.onAdd,
+                       UpdateFunc: ctl.onUpdate,
+                       DeleteFunc: ctl.onDelete,
+               },
+       )
+       return ctl
+}
+
+func (c *apisixTlsController) run(ctx context.Context) {
+       log.Info("ApisixTls controller started")
+       defer log.Info("ApisixTls controller exited")
+       if ok := cache.WaitForCacheSync(ctx.Done(), 
c.controller.apisixTlsInformer.HasSynced, 
c.controller.secretInformer.HasSynced); !ok {
+               log.Errorf("informers sync failed")
+               return
+       }
+       for i := 0; i < c.workers; i++ {
+               go c.runWorker(ctx)
+       }
+
+       <-ctx.Done()
+       c.workqueue.ShutDown()
+}
+
+func (c *apisixTlsController) runWorker(ctx context.Context) {
+       for {
+               obj, quit := c.workqueue.Get()
+               if quit {
+                       return
+               }
+               err := c.sync(ctx, obj.(*types.Event))
+               c.workqueue.Done(obj)
+               c.handleSyncErr(obj, err)
+       }
+}
+
+func (c *apisixTlsController) sync(ctx context.Context, ev *types.Event) error 
{
+       key := ev.Object.(string)
+       namespace, name, err := cache.SplitMetaNamespaceKey(key)
+       if err != nil {
+               log.Errorf("found ApisixTls resource with invalid meta 
namespace key %s: %s", key, err)
+               return err
+       }
+
+       tls, err := 
c.controller.apisixTlsLister.ApisixTlses(namespace).Get(name)
+       if err != nil {
+               if !k8serrors.IsNotFound(err) {
+                       log.Errorf("failed to get ApisixTls %s: %s", key, err)
+                       return err
+               }
+               if ev.Type != types.EventDelete {
+                       log.Warnf("ApisixTls %s was deleted before it can be 
delivered", key)
+                       // Don't need to retry.
+                       return nil
+               }
+       }
+       if ev.Type == types.EventDelete {
+               if tls != nil {
+                       // We still find the resource while we are processing 
the DELETE event,
+                       // that means object with same namespace and name was 
created, discarding
+                       // this stale DELETE event.
+                       log.Warnf("discard the stale ApisixTls delete event 
since the %s exists", key)
+                       return nil
+               }
+               tls = ev.Tombstone.(*configv1.ApisixTls)
+       }
+
+       ssl, err := c.controller.translator.TranslateSSL(tls)
+       if err != nil {
+               log.Errorw("failed to translate ApisixTls",
+                       zap.Error(err),
+                       zap.Any("ApisixTls", tls),
+               )
+               return err
+       }
+       log.Debug("got SSL object from ApisixTls",
+               zap.Any("ssl", ssl),
+               zap.Any("ApisixTls", tls),
+       )
+
+       secretKey := tls.Spec.Secret.Namespace + "_" + tls.Spec.Secret.Name
+       c.syncSecretSSL(secretKey, ssl, ev.Type)
+
+       if err := c.controller.syncSSL(ctx, ssl, ev.Type); err != nil {
+               log.Errorw("failed to sync SSL to APISIX",
+                       zap.Error(err),
+                       zap.Any("ssl", ssl),
+               )
+               return err
+       }
+       return err
+}
+
+func (c *apisixTlsController) syncSecretSSL(key string, ssl *v1.Ssl, event 
types.EventType) {
+       if ssls, ok := c.controller.secretSSLMap.Load(key); ok {
+               sslMap := ssls.(*sync.Map)
+               switch event {
+               case types.EventDelete:
+                       sslMap.Delete(ssl.ID)
+                       c.controller.secretSSLMap.Store(key, sslMap)
+               default:
+                       sslMap.Store(ssl.ID, ssl)
+                       c.controller.secretSSLMap.Store(key, sslMap)
+               }
+       } else if event != types.EventDelete {
+               sslMap := new(sync.Map)
+               sslMap.Store(ssl.ID, ssl)
+               c.controller.secretSSLMap.Store(key, sslMap)
+       }
+}
+
+func (c *apisixTlsController) handleSyncErr(obj interface{}, err error) {
+       if err == nil {
+               c.workqueue.Forget(obj)
+               return
+       }
+       log.Warnw("sync ApisixTls failed, will retry",
+               zap.Any("object", obj),
+               zap.Error(err),
+       )
+       c.workqueue.AddRateLimited(obj)
+}
+
+func (c *apisixTlsController) onAdd(obj interface{}) {
+       key, err := cache.MetaNamespaceKeyFunc(obj)
+       if err != nil {
+               log.Errorf("found ApisixTls object with bad namespace/name: %s, 
ignore it", err)
+               return
+       }
+       if !c.controller.namespaceWatching(key) {
+               return
+       }
+       log.Debugw("ApisixTls add event arrived",
+               zap.Any("object", obj),
+       )
+       c.workqueue.AddRateLimited(&types.Event{
+               Type:   types.EventAdd,
+               Object: key,
+       })
+}
+
+func (c *apisixTlsController) onUpdate(prev, curr interface{}) {
+       oldTls := prev.(*configv1.ApisixTls)
+       newTls := curr.(*configv1.ApisixTls)
+       if oldTls.GetResourceVersion() == newTls.GetResourceVersion() {
+               return
+       }
+       key, err := cache.MetaNamespaceKeyFunc(curr)
+       if err != nil {
+               log.Errorf("found ApisixTls object with bad namespace/name: %s, 
ignore it", err)
+               return
+       }
+       if !c.controller.namespaceWatching(key) {
+               return
+       }
+       log.Debugw("ApisixTls update event arrived",
+               zap.Any("new object", curr),
+               zap.Any("old object", prev),
+       )
+       c.workqueue.AddRateLimited(&types.Event{
+               Type:   types.EventUpdate,
+               Object: key,
+       })
+}
+
+func (c *apisixTlsController) onDelete(obj interface{}) {
+       tls, ok := obj.(*configv1.ApisixTls)
+       if !ok {
+               tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
+               if !ok {
+                       return
+               }
+               tls, ok = tombstone.Obj.(*configv1.ApisixTls)
+               if !ok {
+                       return
+               }
+       }
+       key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
+       if err != nil {
+               log.Errorf("found ApisixTls resource with bad meta namespace 
key: %s", err)
+               return
+       }
+       if !c.controller.namespaceWatching(key) {
+               return
+       }
+       log.Debugw("ApisixTls delete event arrived",
+               zap.Any("final state", obj),
+       )
+       c.workqueue.AddRateLimited(&types.Event{
+               Type:      types.EventDelete,
+               Object:    key,
+               Tombstone: tls,
+       })
+}
diff --git a/pkg/ingress/controller/apisix_upstream.go 
b/pkg/ingress/apisix_upstream.go
similarity index 99%
rename from pkg/ingress/controller/apisix_upstream.go
rename to pkg/ingress/apisix_upstream.go
index 75dd1ba..28b2c9f 100644
--- a/pkg/ingress/controller/apisix_upstream.go
+++ b/pkg/ingress/apisix_upstream.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
diff --git a/pkg/ingress/controller/controller.go b/pkg/ingress/controller.go
similarity index 89%
rename from pkg/ingress/controller/controller.go
rename to pkg/ingress/controller.go
index 35d46f9..a29cbbb 100644
--- a/pkg/ingress/controller/controller.go
+++ b/pkg/ingress/controller.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
@@ -24,7 +24,6 @@ import (
        v1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/runtime"
-       "k8s.io/client-go/informers"
        "k8s.io/client-go/kubernetes"
        listerscorev1 "k8s.io/client-go/listers/core/v1"
        "k8s.io/client-go/tools/cache"
@@ -35,23 +34,16 @@ import (
        "github.com/apache/apisix-ingress-controller/pkg/apisix"
        "github.com/apache/apisix-ingress-controller/pkg/config"
        "github.com/apache/apisix-ingress-controller/pkg/kube"
-       clientset 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned"
        crdclientset 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned"
        
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/informers/externalversions"
        listersv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/listers/config/v1"
        "github.com/apache/apisix-ingress-controller/pkg/kube/translation"
        "github.com/apache/apisix-ingress-controller/pkg/log"
        "github.com/apache/apisix-ingress-controller/pkg/metrics"
-       "github.com/apache/apisix-ingress-controller/pkg/seven/conf"
+       "github.com/apache/apisix-ingress-controller/pkg/types"
+       apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
 
-// recover any exception
-func recoverException() {
-       if err := recover(); err != nil {
-               log.Error(err)
-       }
-}
-
 // Controller is the ingress apisix controller object.
 type Controller struct {
        name               string
@@ -66,6 +58,9 @@ type Controller struct {
        crdClientset       crdclientset.Interface
        metricsCollector   metrics.Collector
        crdInformerFactory externalversions.SharedInformerFactory
+       // this map enrolls which ApisixTls objects refer to a Kubernetes
+       // Secret object.
+       secretSSLMap *sync.Map
 
        // common informers and listers
        epInformer             cache.SharedIndexInformer
@@ -80,6 +75,8 @@ type Controller struct {
        apisixUpstreamLister   listersv1.ApisixUpstreamLister
        apisixRouteLister      kube.ApisixRouteLister
        apisixRouteInformer    cache.SharedIndexInformer
+       apisixTlsLister        listersv1.ApisixTlsLister
+       apisixTlsInformer      cache.SharedIndexInformer
 
        // resource controllers
        endpointsController *endpointsController
@@ -88,6 +85,7 @@ type Controller struct {
 
        apisixUpstreamController *apisixUpstreamController
        apisixRouteController    *apisixRouteController
+       apisixTlsController      *apisixTlsController
 }
 
 // NewController creates an ingress apisix controller object.
@@ -101,7 +99,6 @@ func NewController(cfg *config.Config) (*Controller, error) {
        if err != nil {
                return nil, err
        }
-       conf.SetAPISIXClient(client)
 
        if err := kube.InitInformer(cfg); err != nil {
                return nil, err
@@ -160,6 +157,7 @@ func NewController(cfg *config.Config) (*Controller, error) 
{
                crdClientset:       crdClientset,
                crdInformerFactory: sharedInformerFactory,
                watchingNamespace:  watchingNamespace,
+               secretSSLMap:       new(sync.Map),
 
                epInformer:             
kube.CoreSharedInformerFactory.Core().V1().Endpoints().Informer(),
                epLister:               
kube.CoreSharedInformerFactory.Core().V1().Endpoints().Lister(),
@@ -173,16 +171,20 @@ func NewController(cfg *config.Config) (*Controller, 
error) {
                apisixRouteLister:      apisixRouteLister,
                apisixUpstreamInformer: 
sharedInformerFactory.Apisix().V1().ApisixUpstreams().Informer(),
                apisixUpstreamLister:   
sharedInformerFactory.Apisix().V1().ApisixUpstreams().Lister(),
+               apisixTlsInformer:      
sharedInformerFactory.Apisix().V1().ApisixTlses().Informer(),
+               apisixTlsLister:        
sharedInformerFactory.Apisix().V1().ApisixTlses().Lister(),
        }
        c.translator = translation.NewTranslator(&translation.TranslatorOptions{
                EndpointsLister:      c.epLister,
                ServiceLister:        c.svcLister,
                ApisixUpstreamLister: c.apisixUpstreamLister,
+               SecretLister:         c.secretLister,
        })
 
        c.endpointsController = c.newEndpointsController()
        c.apisixUpstreamController = c.newApisixUpstreamController()
        c.apisixRouteController = c.newApisixRouteController()
+       c.apisixTlsController = c.newApisixTlsController()
        c.ingressController = c.newIngressController()
        c.secretController = c.newSecretController()
 
@@ -307,6 +309,18 @@ func (c *Controller) run(ctx context.Context) {
                c.ingressInformer.Run(ctx.Done())
        })
        c.goAttach(func() {
+               c.apisixRouteInformer.Run(ctx.Done())
+       })
+       c.goAttach(func() {
+               c.apisixUpstreamInformer.Run(ctx.Done())
+       })
+       c.goAttach(func() {
+               c.secretInformer.Run(ctx.Done())
+       })
+       c.goAttach(func() {
+               c.apisixTlsInformer.Run(ctx.Done())
+       })
+       c.goAttach(func() {
                c.endpointsController.run(ctx)
        })
        c.goAttach(func() {
@@ -319,27 +333,12 @@ func (c *Controller) run(ctx context.Context) {
                c.apisixRouteController.run(ctx)
        })
        c.goAttach(func() {
-               c.secretInformer.Run(ctx.Done())
+               c.apisixTlsController.run(ctx)
        })
        c.goAttach(func() {
                c.secretController.run(ctx)
        })
 
-       ac := &Api6Controller{
-               KubeClientSet:             c.clientset,
-               Api6ClientSet:             c.crdClientset,
-               SharedInformerFactory:     c.crdInformerFactory,
-               CoreSharedInformerFactory: kube.CoreSharedInformerFactory,
-               Stop:                      ctx.Done(),
-       }
-
-       // ApisixTLS
-       ac.ApisixTLS(c)
-
-       c.goAttach(func() {
-               ac.SharedInformerFactory.Start(ctx.Done())
-       })
-
        <-ctx.Done()
        c.wg.Wait()
 }
@@ -362,21 +361,16 @@ func (c *Controller) namespaceWatching(key string) (ok 
bool) {
        return
 }
 
-type Api6Controller struct {
-       KubeClientSet             kubernetes.Interface
-       Api6ClientSet             clientset.Interface
-       SharedInformerFactory     externalversions.SharedInformerFactory
-       CoreSharedInformerFactory informers.SharedInformerFactory
-       Stop                      <-chan struct{}
-}
-
-func (api6 *Api6Controller) ApisixTLS(controller *Controller) {
-       atc := BuildApisixTlsController(
-               api6.KubeClientSet,
-               api6.Api6ClientSet,
-               api6.SharedInformerFactory.Apisix().V1().ApisixTlses(),
-               controller)
-       if err := atc.Run(api6.Stop); err != nil {
-               log.Errorf("failed to run ApisixTlsController: %s", err)
+func (c *Controller) syncSSL(ctx context.Context, ssl *apisixv1.Ssl, event 
types.EventType) error {
+       var (
+               err error
+       )
+       if event == types.EventDelete {
+               err = c.apisix.Cluster("").SSL().Delete(ctx, ssl)
+       } else if event == types.EventUpdate {
+               _, err = c.apisix.Cluster("").SSL().Update(ctx, ssl)
+       } else {
+               _, err = c.apisix.Cluster("").SSL().Create(ctx, ssl)
        }
+       return err
 }
diff --git a/pkg/ingress/controller/apisix_tls.go 
b/pkg/ingress/controller/apisix_tls.go
deleted file mode 100644
index 14a0131..0000000
--- a/pkg/ingress/controller/apisix_tls.go
+++ /dev/null
@@ -1,254 +0,0 @@
-// 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 controller
-
-import (
-       "fmt"
-       "sync"
-       "time"
-
-       "k8s.io/apimachinery/pkg/api/errors"
-       "k8s.io/apimachinery/pkg/util/runtime"
-       "k8s.io/apimachinery/pkg/util/wait"
-       "k8s.io/client-go/kubernetes"
-       "k8s.io/client-go/kubernetes/scheme"
-       "k8s.io/client-go/tools/cache"
-       "k8s.io/client-go/util/workqueue"
-
-       "github.com/apache/apisix-ingress-controller/pkg/ingress/apisix"
-       configv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1"
-       clientset 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned"
-       apisixscheme 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/clientset/versioned/scheme"
-       informersv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/informers/externalversions/config/v1"
-       listersv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/client/listers/config/v1"
-       "github.com/apache/apisix-ingress-controller/pkg/log"
-       "github.com/apache/apisix-ingress-controller/pkg/seven/state"
-       v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-var (
-       // the struct of secretSSLMap is a map[secretKey string]map[sslKey 
string]bool
-       // the xxxKey is format as namespace + "/" + name
-       secretSSLMap = sync.Map{}
-)
-
-type ApisixTLSController struct {
-       controller      *Controller
-       kubeclientset   kubernetes.Interface
-       apisixClientset clientset.Interface
-       apisixTLSList   listersv1.ApisixTlsLister
-       apisixTLSSynced cache.InformerSynced
-       workqueue       workqueue.RateLimitingInterface
-}
-
-type TlsQueueObj struct {
-       Key    string              `json:"key"`
-       OldObj *configv1.ApisixTls `json:"old_obj"`
-       Ope    string              `json:"ope"` // add / update / delete
-}
-
-func BuildApisixTlsController(
-       kubeclientset kubernetes.Interface,
-       apisixTLSClientset clientset.Interface,
-       apisixTLSInformer informersv1.ApisixTlsInformer,
-       root *Controller) *ApisixTLSController {
-
-       runtime.Must(apisixscheme.AddToScheme(scheme.Scheme))
-       controller := &ApisixTLSController{
-               controller:      root,
-               kubeclientset:   kubeclientset,
-               apisixClientset: apisixTLSClientset,
-               apisixTLSList:   apisixTLSInformer.Lister(),
-               apisixTLSSynced: apisixTLSInformer.Informer().HasSynced,
-               workqueue:       
workqueue.NewNamedRateLimitingQueue(workqueue.NewItemFastSlowRateLimiter(1*time.Second,
 60*time.Second, 5), "ApisixTlses"),
-       }
-       apisixTLSInformer.Informer().AddEventHandler(
-               cache.ResourceEventHandlerFuncs{
-                       AddFunc:    controller.addFunc,
-                       UpdateFunc: controller.updateFunc,
-                       DeleteFunc: controller.deleteFunc,
-               })
-       return controller
-}
-
-func (c *ApisixTLSController) Run(stop <-chan struct{}) error {
-       if ok := cache.WaitForCacheSync(stop); !ok {
-               log.Errorf("sync ApisixTLS cache failed")
-               return fmt.Errorf("failed to wait for caches to sync")
-       }
-       go wait.Until(c.runWorker, time.Second, stop)
-       return nil
-}
-
-func (c *ApisixTLSController) runWorker() {
-       for c.processNextWorkItem() {
-       }
-}
-
-func (c *ApisixTLSController) processNextWorkItem() bool {
-       defer recoverException()
-       obj, shutdown := c.workqueue.Get()
-       if shutdown {
-               return false
-       }
-       err := func(obj interface{}) error {
-               defer c.workqueue.Done(obj)
-               var key string
-               var ok bool
-
-               var tqo *TlsQueueObj
-               if tqo, ok = obj.(*TlsQueueObj); !ok {
-                       c.workqueue.Forget(obj)
-                       return fmt.Errorf("expected TlsQueueObj in workqueue 
but got %#v", obj)
-               }
-               if err := c.syncHandler(tqo); err != nil {
-                       c.workqueue.AddRateLimited(tqo)
-                       log.Errorf("sync tls %s failed", tqo.Key)
-                       return fmt.Errorf("error syncing '%s': %s", key, 
err.Error())
-               }
-
-               c.workqueue.Forget(obj)
-               return nil
-       }(obj)
-       if err != nil {
-               runtime.HandleError(err)
-       }
-       return true
-}
-
-func (c *ApisixTLSController) syncHandler(tqo *TlsQueueObj) error {
-       namespace, name, err := cache.SplitMetaNamespaceKey(tqo.Key)
-       if err != nil {
-               log.Errorf("invalid resource key: %s", tqo.Key)
-               return fmt.Errorf("invalid resource key: %s", tqo.Key)
-       }
-       apisixTlsYaml := tqo.OldObj
-       if tqo.Ope == state.Delete {
-               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.ApisixTlses(namespace).Get(name)
-               if err != nil {
-                       if errors.IsNotFound(err) {
-                               log.Infof("apisixTls %s is removed", tqo.Key)
-                               return nil
-                       }
-                       runtime.HandleError(fmt.Errorf("failed to list 
apisixTls %s/%s", tqo.Key, err.Error()))
-                       return err
-               }
-       }
-
-       apisixTls := apisix.ApisixTLSCRD(*apisixTlsYaml)
-       sc := &apisix.SecretClient{}
-       if tls, err := apisixTls.Convert(sc); err != nil {
-               return err
-       } else {
-               // sync to apisix
-               log.Debug(tls)
-               log.Debug(tqo)
-               err = state.SyncSsl(tls, tqo.Ope)
-               // sync SyncSecretSSL
-               secretKey := fmt.Sprintf("%s_%s", 
apisixTls.Spec.Secret.Namespace, apisixTls.Spec.Secret.Name)
-               SyncSecretSSL(secretKey, tls, tqo.Ope)
-               return err
-       }
-}
-
-// SyncSecretSSL sync the secretSSLMap
-// the struct of secretSSLMap is a map[secretKey string]map[sslKey string]bool
-// the xxxKey is format as namespace + "_" + name
-func SyncSecretSSL(key string, ssl *v1.Ssl, operator string) {
-       ssls, ok := secretSSLMap.Load(key)
-       if ok {
-               sslMap := ssls.(*sync.Map)
-               switch operator {
-               case state.Delete:
-                       sslMap.Delete(ssl.ID)
-                       secretSSLMap.Store(key, sslMap)
-               default:
-                       sslMap.Store(ssl.ID, ssl)
-                       secretSSLMap.Store(key, sslMap)
-               }
-       } else {
-               if operator != state.Delete {
-                       sslMap := &sync.Map{}
-                       sslMap.Store(ssl.ID, ssl)
-                       secretSSLMap.Store(key, sslMap)
-               }
-       }
-
-}
-
-func (c *ApisixTLSController) addFunc(obj interface{}) {
-       var key string
-       var err error
-       if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
-               runtime.HandleError(err)
-               return
-       }
-       if !c.controller.namespaceWatching(key) {
-               return
-       }
-       rqo := &TlsQueueObj{Key: key, OldObj: nil, Ope: state.Create}
-       c.workqueue.AddRateLimited(rqo)
-}
-
-func (c *ApisixTLSController) updateFunc(oldObj, newObj interface{}) {
-       oldTls := oldObj.(*configv1.ApisixTls)
-       newTls := newObj.(*configv1.ApisixTls)
-       if oldTls.ResourceVersion == newTls.ResourceVersion {
-               return
-       }
-       var key string
-       var err error
-       if key, err = cache.MetaNamespaceKeyFunc(newObj); err != nil {
-               runtime.HandleError(err)
-               return
-       }
-       if !c.controller.namespaceWatching(key) {
-               return
-       }
-       rqo := &TlsQueueObj{Key: key, OldObj: oldTls, Ope: state.Update}
-       c.workqueue.AddRateLimited(rqo)
-}
-
-func (c *ApisixTLSController) deleteFunc(obj interface{}) {
-       oldTls, ok := obj.(*configv1.ApisixTls)
-       if !ok {
-               oldState, ok := obj.(cache.DeletedFinalStateUnknown)
-               if !ok {
-                       return
-               }
-               oldTls, ok = oldState.Obj.(*configv1.ApisixTls)
-               if !ok {
-                       return
-               }
-       }
-       var key string
-       var err error
-       key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
-       if err != nil {
-               runtime.HandleError(err)
-               return
-       }
-       if !c.controller.namespaceWatching(key) {
-               return
-       }
-       rqo := &TlsQueueObj{Key: key, OldObj: oldTls, Ope: state.Delete}
-       c.workqueue.AddRateLimited(rqo)
-}
diff --git a/pkg/ingress/controller/endpoint.go b/pkg/ingress/endpoint.go
similarity index 99%
rename from pkg/ingress/controller/endpoint.go
rename to pkg/ingress/endpoint.go
index ad22a36..80c6d06 100644
--- a/pkg/ingress/controller/endpoint.go
+++ b/pkg/ingress/endpoint.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
diff --git a/pkg/ingress/controller/ingress.go b/pkg/ingress/ingress.go
similarity index 99%
rename from pkg/ingress/controller/ingress.go
rename to pkg/ingress/ingress.go
index 690e819..a9034d2 100644
--- a/pkg/ingress/controller/ingress.go
+++ b/pkg/ingress/ingress.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
diff --git a/pkg/ingress/controller/ingress_test.go 
b/pkg/ingress/ingress_test.go
similarity index 99%
rename from pkg/ingress/controller/ingress_test.go
rename to pkg/ingress/ingress_test.go
index 1e17f4c..08396dc 100644
--- a/pkg/ingress/controller/ingress_test.go
+++ b/pkg/ingress/ingress_test.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "testing"
diff --git a/pkg/ingress/controller/manifest.go b/pkg/ingress/manifest.go
similarity index 99%
rename from pkg/ingress/controller/manifest.go
rename to pkg/ingress/manifest.go
index 709f986..25901d1 100644
--- a/pkg/ingress/controller/manifest.go
+++ b/pkg/ingress/manifest.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "context"
diff --git a/pkg/ingress/controller/manifest_test.go 
b/pkg/ingress/manifest_test.go
similarity index 99%
rename from pkg/ingress/controller/manifest_test.go
rename to pkg/ingress/manifest_test.go
index 811aefc..9d568e6 100644
--- a/pkg/ingress/controller/manifest_test.go
+++ b/pkg/ingress/manifest_test.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 import (
        "testing"
diff --git a/pkg/ingress/controller/secret.go b/pkg/ingress/secret.go
similarity index 74%
rename from pkg/ingress/controller/secret.go
rename to pkg/ingress/secret.go
index 5268a0b..d831d33 100644
--- a/pkg/ingress/controller/secret.go
+++ b/pkg/ingress/secret.go
@@ -13,23 +13,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package controller
+package ingress
 
 import (
        "context"
-       "fmt"
        "sync"
        "time"
 
        "go.uber.org/zap"
        corev1 "k8s.io/api/core/v1"
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
-       "k8s.io/apimachinery/pkg/util/runtime"
        "k8s.io/client-go/tools/cache"
        "k8s.io/client-go/util/workqueue"
 
+       "github.com/apache/apisix-ingress-controller/pkg/kube/translation"
        "github.com/apache/apisix-ingress-controller/pkg/log"
-       "github.com/apache/apisix-ingress-controller/pkg/seven/state"
        "github.com/apache/apisix-ingress-controller/pkg/types"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
@@ -67,42 +65,26 @@ func (c *secretController) run(ctx context.Context) {
                return
        }
 
-       handler := func() {
-               for {
-                       obj, shutdown := c.workqueue.Get()
-                       if shutdown {
-                               return
-                       }
-                       err := func(obj interface{}) error {
-                               defer c.workqueue.Done(obj)
-                               event := obj.(*types.Event)
-                               if key, ok := event.Object.(string); !ok {
-                                       c.workqueue.Forget(obj)
-                                       return fmt.Errorf("expected Secret in 
workqueue but got %#v", obj)
-                               } else {
-                                       if err := c.sync(ctx, event); err != 
nil {
-                                               c.workqueue.AddRateLimited(obj)
-                                               log.Errorf("sync secret with 
ssl %s failed", key)
-                                               return fmt.Errorf("error 
syncing '%s': %s", key, err.Error())
-                                       }
-                                       c.workqueue.Forget(obj)
-                                       return nil
-                               }
-                       }(obj)
-                       if err != nil {
-                               runtime.HandleError(err)
-                       }
-               }
-       }
-
        for i := 0; i < c.workers; i++ {
-               go handler()
+               go c.runWorker(ctx)
        }
 
        <-ctx.Done()
        c.workqueue.ShutDown()
 }
 
+func (c *secretController) runWorker(ctx context.Context) {
+       for {
+               obj, quit := c.workqueue.Get()
+               if quit {
+                       return
+               }
+               err := c.sync(ctx, obj.(*types.Event))
+               c.workqueue.Done(obj)
+               c.handleSyncErr(obj, err)
+       }
+}
+
 func (c *secretController) sync(ctx context.Context, ev *types.Event) error {
        key := ev.Object.(string)
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
@@ -143,21 +125,55 @@ func (c *secretController) sync(ctx context.Context, ev 
*types.Event) error {
        }
        // sync SSL in APISIX which is store in secretSSLMap
        // FixMe Need to update the status of CRD ApisixTls
-       ssls, ok := secretSSLMap.Load(secretMapkey)
-       if ok {
-               sslMap := ssls.(*sync.Map)
-               sslMap.Range(func(_, v interface{}) bool {
-                       ssl := v.(*apisixv1.Ssl)
-                       // sync ssl
-                       ssl.Cert = string(sec.Data["cert"])
-                       ssl.Key = string(sec.Data["key"])
-                       ssl.FullName = ssl.ID
-                       return state.SyncSsl(ssl, ev.Type.String()) == nil
-               })
+       ssls, ok := c.controller.secretSSLMap.Load(secretMapkey)
+       if !ok {
+               // This secret is not concerned.
+               return nil
+       }
+       cert, ok := sec.Data["cert"]
+       if !ok {
+               return translation.ErrEmptyCert
        }
+       pkey, ok := sec.Data["key"]
+       if !ok {
+               return translation.ErrEmptyPrivKey
+       }
+       sslMap := ssls.(*sync.Map)
+       sslMap.Range(func(_, v interface{}) bool {
+               ssl := v.(*apisixv1.Ssl)
+               // sync ssl
+               ssl.Cert = string(cert)
+               ssl.Key = string(pkey)
+
+               // Use another goroutine to send requests, to avoid
+               // long time lock occupying.
+               go func(ssl *apisixv1.Ssl) {
+                       err := c.controller.syncSSL(ctx, ssl, ev.Type)
+                       if err != nil {
+                               log.Errorw("failed to sync ssl to APISIX",
+                                       zap.Error(err),
+                                       zap.Any("ssl", ssl),
+                                       zap.Any("secret", sec),
+                               )
+                       }
+               }(ssl)
+               return true
+       })
        return err
 }
 
+func (c *secretController) handleSyncErr(obj interface{}, err error) {
+       if err == nil {
+               c.workqueue.Forget(obj)
+               return
+       }
+       log.Warnw("sync ApisixTls failed, will retry",
+               zap.Any("object", obj),
+               zap.Error(err),
+       )
+       c.workqueue.AddRateLimited(obj)
+}
+
 func (c *secretController) onAdd(obj interface{}) {
        key, err := cache.MetaNamespaceKeyFunc(obj)
        if err != nil {
@@ -168,6 +184,9 @@ func (c *secretController) onAdd(obj interface{}) {
                return
        }
 
+       log.Debugw("secret add event arrived",
+               zap.Any("object", obj),
+       )
        c.workqueue.AddRateLimited(&types.Event{
                Type:   types.EventAdd,
                Object: key,
@@ -189,6 +208,10 @@ func (c *secretController) onUpdate(prev, curr 
interface{}) {
        if !c.controller.namespaceWatching(key) {
                return
        }
+       log.Debugw("secret update event arrived",
+               zap.Any("new object", curr),
+               zap.Any("old object", prev),
+       )
        c.workqueue.AddRateLimited(&types.Event{
                Type:   types.EventUpdate,
                Object: key,
@@ -208,7 +231,7 @@ func (c *secretController) onDelete(obj interface{}) {
 
        key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
        if err != nil {
-               log.Errorf("found secret resource with bad meta namesapce key: 
%s", err)
+               log.Errorf("found secret resource with bad meta namespace key: 
%s", err)
                return
        }
        // FIXME Refactor Controller.namespaceWatching to just use
@@ -217,6 +240,9 @@ func (c *secretController) onDelete(obj interface{}) {
        if !c.controller.namespaceWatching(key) {
                return
        }
+       log.Debugw("secret delete event arrived",
+               zap.Any("final state", sec),
+       )
        c.workqueue.AddRateLimited(&types.Event{
                Type:      types.EventDelete,
                Object:    key,
diff --git a/pkg/ingress/controller/types.go b/pkg/ingress/types.go
similarity index 97%
rename from pkg/ingress/controller/types.go
rename to pkg/ingress/types.go
index d857ef6..640ba00 100644
--- a/pkg/ingress/controller/types.go
+++ b/pkg/ingress/types.go
@@ -12,7 +12,7 @@
 // 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 controller
+package ingress
 
 const (
        ADD           = "ADD"
diff --git a/pkg/kube/translation/apisix_ssl.go 
b/pkg/kube/translation/apisix_ssl.go
new file mode 100644
index 0000000..9572b3b
--- /dev/null
+++ b/pkg/kube/translation/apisix_ssl.go
@@ -0,0 +1,58 @@
+// 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 translation
+
+import (
+       "errors"
+
+       "github.com/apache/apisix-ingress-controller/pkg/id"
+       configv1 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1"
+       apisix "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+       apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+)
+
+var (
+       // ErrEmptyCert means the cert field in Kubernetes Secret is not found.
+       ErrEmptyCert = errors.New("missing cert field")
+       // ErrEmptyPrivKey means the key field in Kubernetes Secret is not 
found.
+       ErrEmptyPrivKey = errors.New("missing key field")
+)
+
+func (t *translator) TranslateSSL(tls *configv1.ApisixTls) (*apisixv1.Ssl, 
error) {
+       s, err := 
t.SecretLister.Secrets(tls.Spec.Secret.Namespace).Get(tls.Spec.Secret.Name)
+       if err != nil {
+               return nil, err
+       }
+       cert, ok := s.Data["cert"]
+       if !ok {
+               return nil, ErrEmptyCert
+       }
+       key, ok := s.Data["key"]
+       if !ok {
+               return nil, ErrEmptyPrivKey
+       }
+       var snis []string
+       snis = append(snis, tls.Spec.Hosts...)
+       fullname := tls.Namespace + "_" + tls.Name
+       ssl := &apisix.Ssl{
+               ID:       id.GenID(fullname),
+               FullName: fullname,
+               Snis:     snis,
+               Cert:     string(cert),
+               Key:      string(key),
+               Status:   1,
+       }
+       return ssl, nil
+}
diff --git a/pkg/kube/translation/translator.go 
b/pkg/kube/translation/translator.go
index f7843b6..705bf35 100644
--- a/pkg/kube/translation/translator.go
+++ b/pkg/kube/translation/translator.go
@@ -64,6 +64,8 @@ type Translator interface {
        // TranslateRouteV2alpha1 translates the configv2alph1.ApisixRoute 
object into several Route
        // and Upstream resources.
        TranslateRouteV2alpha1(*configv2alpha1.ApisixRoute) ([]*apisixv1.Route, 
[]*apisixv1.Upstream, error)
+       // TranslateSSL translates the configv2alpha1.ApisixTls object into the 
APISIX SSL resource.
+       TranslateSSL(*configv1.ApisixTls) (*apisixv1.Ssl, error)
 }
 
 // TranslatorOptions contains options to help Translator
@@ -72,6 +74,7 @@ type TranslatorOptions struct {
        EndpointsLister      listerscorev1.EndpointsLister
        ServiceLister        listerscorev1.ServiceLister
        ApisixUpstreamLister listersv1.ApisixUpstreamLister
+       SecretLister         listerscorev1.SecretLister
 }
 
 type translator struct {
diff --git a/pkg/seven/apisix/event.go b/pkg/seven/apisix/event.go
deleted file mode 100644
index 64bd3d9..0000000
--- a/pkg/seven/apisix/event.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 apisix
-
-// define event for workflow
-
-type Event struct {
-       Method string               // ADD UPDATE DELETE
-       Kind   string               // route service upstream
-       Func   func(...interface{}) // callback
-}
diff --git a/pkg/seven/conf/conf.go b/pkg/seven/conf/conf.go
deleted file mode 100644
index 6be1b8a..0000000
--- a/pkg/seven/conf/conf.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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 conf
-
-import (
-       "github.com/apache/apisix-ingress-controller/pkg/apisix"
-       "github.com/apache/apisix-ingress-controller/pkg/log"
-)
-
-var (
-       BaseUrl  = "http://172.16.20.90:30116/apisix/admin";
-       UrlGroup = make(map[string]string)
-       Client   apisix.APISIX
-)
-
-func SetBaseUrl(url string) {
-       BaseUrl = url
-}
-
-func AddGroup(group string) {
-       if group != "" {
-               err := Client.AddCluster(&apisix.ClusterOptions{
-                       Name:    group,
-                       BaseURL: "http://"; + group + "/apisix/admin",
-               })
-               if err != nil {
-                       if err == apisix.ErrDuplicatedCluster {
-                               log.Errorf("failed to create cluster %s: %s", 
group, err)
-                       } else {
-                               log.Infof("cluster %s already exists", group)
-                       }
-               }
-       }
-}
-
-func SetAPISIXClient(c apisix.APISIX) {
-       Client = c
-}
diff --git a/pkg/seven/conf/conf_test.go b/pkg/seven/conf/conf_test.go
deleted file mode 100644
index 1540cca..0000000
--- a/pkg/seven/conf/conf_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 conf
-
-import "testing"
-
-func Test_map(t *testing.T) {
-       m1 := make(map[string]string)
-       m1["a"] = "aa"
-       m1["b"] = "bb"
-       t.Log(m1["c"] == "")
-}
diff --git a/pkg/seven/state/event.go b/pkg/seven/state/event.go
deleted file mode 100644
index 8c354e0..0000000
--- a/pkg/seven/state/event.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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 state
-
-const (
-       Create = "create"
-       Update = "update"
-       Delete = "delete"
-)
diff --git a/pkg/seven/state/solver.go b/pkg/seven/state/solver.go
deleted file mode 100644
index d17cdeb..0000000
--- a/pkg/seven/state/solver.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 state
-
-import (
-       "context"
-
-       "github.com/apache/apisix-ingress-controller/pkg/seven/conf"
-       v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-type CRDStatus struct {
-       Id     string `json:"id"`
-       Status string `json:"status"`
-       Err    error  `json:"err"`
-}
-
-func SyncSsl(ssl *v1.Ssl, method string) error {
-       var cluster string
-       if ssl.Group != "" {
-               cluster = ssl.Group
-       }
-       switch method {
-       case Create:
-               _, err := 
conf.Client.Cluster(cluster).SSL().Create(context.TODO(), ssl)
-               return err
-       case Update:
-               _, err := 
conf.Client.Cluster(cluster).SSL().Update(context.TODO(), ssl)
-               return err
-       case Delete:
-               return 
conf.Client.Cluster(cluster).SSL().Delete(context.TODO(), ssl)
-       }
-       return nil
-}
diff --git a/pkg/seven/utils/diff.go b/pkg/seven/utils/diff.go
deleted file mode 100644
index 5a48256..0000000
--- a/pkg/seven/utils/diff.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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 utils
-
-import (
-       "encoding/json"
-
-       "github.com/golang/glog"
-       "github.com/yudai/gojsondiff"
-)
-
-var (
-       differ = gojsondiff.New()
-)
-
-func HasDiff(a, b interface{}) (bool, error) {
-       aJSON, err := json.Marshal(a)
-       if err != nil {
-               return false, err
-       }
-       bJSON, err := json.Marshal(b)
-       if err != nil {
-               return false, err
-       }
-       if d, err := differ.Compare(aJSON, bJSON); err != nil {
-               return false, err
-       } else {
-               glog.V(2).Info(d.Deltas())
-               return d.Modified(), nil
-       }
-}
-
-func Diff(a, b interface{}) (gojsondiff.Diff, error) {
-       aJSON, err := json.Marshal(a)
-       if err != nil {
-               return nil, err
-       }
-       bJSON, err := json.Marshal(b)
-       if err != nil {
-               return nil, err
-       }
-       if d, err := differ.Compare(aJSON, bJSON); err != nil {
-               return nil, err
-       } else {
-               return d, nil
-       }
-}
diff --git a/pkg/seven/utils/http.go b/pkg/seven/utils/http.go
deleted file mode 100644
index 9b5a76a..0000000
--- a/pkg/seven/utils/http.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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 utils
-
-import (
-       "fmt"
-       "net/http"
-       "time"
-
-       "gopkg.in/resty.v1"
-)
-
-const timeout = 3000
-
-func Post(url string, bytes []byte) ([]byte, error) {
-       r := resty.New().
-               SetTimeout(time.Duration(timeout)*time.Millisecond).
-               R().
-               SetHeader("content-type", "application/json")
-       r.SetBody(bytes)
-       resp, err := r.Post(url)
-       if err != nil {
-               return nil, err
-       }
-       if resp.StatusCode() != http.StatusOK && resp.StatusCode() != 
http.StatusCreated {
-               return nil, fmt.Errorf("status: %d, body: %s", 
resp.StatusCode(), resp.Body())
-       }
-       return resp.Body(), nil
-}
-
-func Put(url string, bytes []byte) ([]byte, error) {
-       r := resty.New().
-               SetTimeout(time.Duration(timeout)*time.Millisecond).
-               R().
-               SetHeader("content-type", "application/json")
-       r.SetBody(bytes)
-       resp, err := r.Put(url)
-       if err != nil {
-               return nil, err
-       }
-       if resp.StatusCode() != http.StatusOK && resp.StatusCode() != 
http.StatusCreated {
-               return nil, fmt.Errorf("status: %d, body: %s", 
resp.StatusCode(), resp.Body())
-       }
-       return resp.Body(), nil
-}
-
-func Patch(url string, bytes []byte) ([]byte, error) {
-       r := resty.New().
-               SetTimeout(time.Duration(timeout)*time.Millisecond).
-               R().
-               SetHeader("content-type", "application/json")
-       r.SetBody(bytes)
-       resp, err := r.Patch(url)
-       if err != nil {
-               return nil, err
-       }
-       if resp.StatusCode() != http.StatusOK && resp.StatusCode() != 
http.StatusCreated {
-               return nil, fmt.Errorf("status: %d, body: %s", 
resp.StatusCode(), resp.Body())
-       }
-       return resp.Body(), nil
-}
-
-func Delete(url string) ([]byte, error) {
-       r := resty.New().
-               SetTimeout(time.Duration(timeout)*time.Millisecond).
-               R().
-               SetHeader("content-type", "application/json")
-       resp, err := r.Delete(url)
-       if err != nil {
-               return nil, err
-       }
-       if resp.StatusCode() != http.StatusOK && resp.StatusCode() != 
http.StatusNotFound {
-               return nil, fmt.Errorf("status: %d, body: %s", 
resp.StatusCode(), resp.Body())
-       }
-       return resp.Body(), nil
-}
diff --git a/pkg/seven/utils/types.go b/pkg/seven/utils/types.go
deleted file mode 100644
index 6709dc9..0000000
--- a/pkg/seven/utils/types.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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 utils
-
-import "errors"
-
-// ErrNotFound unify Not Found error.
-var ErrNotFound = errors.New("NOT FOUND")
diff --git a/test/e2e/ingress/secret.go b/test/e2e/ingress/secret.go
index 9729cfb..a28e16b 100644
--- a/test/e2e/ingress/secret.go
+++ b/test/e2e/ingress/secret.go
@@ -143,7 +143,7 @@ 
do+oXlr8db++r87a8QQUkizzc6wXD9JffBNo9AO9Ed4HVOukpEA0gqVGBu85N3xW
 jW4KB95bGOTa7r7DM1Up0MbAIwWoeLBGhOIXk7inurZGg+FNjZMA5Lzm6qo=
 -----END RSA PRIVATE KEY-----`
                // key compare
-               key_compare := 
"HrMHUvE9Esvn7GnZ+vAynaIg/8wlB3r0zm0htmnwofaOw61M98WSdvoWLaQa8YKSdemgQUz2W4MYk2rRZcVSzHfJOLRG7g4ieZau6peDYOmPmp/0ZZFpOzBKoWHN3QP/8i/7SF+JX+EDLD2JO2+GM6iR3f2Zj7v0vx+CcoQ1rjxaXNETSSHo8yvW6pdFZOLgJk4rOHKGypnqzygxxamM8Hq7WSPrWhNe47y1QAfz42kBQXRUJpNNd7W749cTsMWCqBlR+8klTlnSFHkjyijBZjg5ihqZsi/8JzHGrmAixZ54ugPgbufD0/ZJdo3w7opJc4WTnUI2GhiBL+ENCA0X1s/6H8JG8zsC50PvxOBpRgK455TTvejm1JHyt0GTh7c4WFEeQSrbEFzS89BpVrPtre2enO38pkILI8ty8r6tIbZzuOJhM6ZpxQQcAe8OUvFuIIlx21yBvlljbu3eH5Hg7X+wtJ
 [...]
+               keyCompare := 
"HrMHUvE9Esvn7GnZ+vAynaIg/8wlB3r0zm0htmnwofaOw61M98WSdvoWLaQa8YKSdemgQUz2W4MYk2rRZcVSzHfJOLRG7g4ieZau6peDYOmPmp/0ZZFpOzBKoWHN3QP/8i/7SF+JX+EDLD2JO2+GM6iR3f2Zj7v0vx+CcoQ1rjxaXNETSSHo8yvW6pdFZOLgJk4rOHKGypnqzygxxamM8Hq7WSPrWhNe47y1QAfz42kBQXRUJpNNd7W749cTsMWCqBlR+8klTlnSFHkjyijBZjg5ihqZsi/8JzHGrmAixZ54ugPgbufD0/ZJdo3w7opJc4WTnUI2GhiBL+ENCA0X1s/6H8JG8zsC50PvxOBpRgK455TTvejm1JHyt0GTh7c4WFEeQSrbEFzS89BpVrPtre2enO38pkILI8ty8r6tIbZzuOJhM6ZpxQQcAe8OUvFuIIlx21yBvlljbu3eH5Hg7X+wtJR
 [...]
                // create secret
                err := s.NewSecret(secretName, cert, key)
                assert.Nil(ginkgo.GinkgoT(), err, "create secret error")
@@ -158,7 +158,7 @@ jW4KB95bGOTa7r7DM1Up0MbAIwWoeLBGhOIXk7inurZGg+FNjZMA5Lzm6qo=
                assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
                assert.Len(ginkgo.GinkgoT(), tls, 1, "tls number not expect")
                assert.Equal(ginkgo.GinkgoT(), cert, tls[0].Cert, "tls cert not 
expect")
-               assert.Equal(ginkgo.GinkgoT(), key_compare, tls[0].Key, "tls 
key not expect")
+               assert.Equal(ginkgo.GinkgoT(), keyCompare, tls[0].Key, "tls key 
not expect")
 
                // check DP
                s.NewAPISIXHttpsClient(host).GET("/ip").WithHeader("Host", 
host).Expect().Status(http.StatusOK).Body().Raw()

Reply via email to