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()