You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by to...@apache.org on 2021/04/13 03:16:32 UTC
[apisix-ingress-controller] branch master updated: chore:
controller tree (#361)
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 <zc...@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()