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

zhangjintao 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 0e1f8d4a fix : The ingress backend is modified several times, 
resulting in residual update events (#1040)
0e1f8d4a is described below

commit 0e1f8d4afdf4d90743ef238872d1e383cdfa93a4
Author: hahayyun <[email protected]>
AuthorDate: Wed Jun 29 09:52:03 2022 +0800

    fix : The ingress backend is modified several times, resulting in residual 
update events (#1040)
---
 pkg/ingress/ingress.go               |   5 +-
 pkg/kube/translation/ingress.go      | 106 +++++++++++++++++++++++++++--------
 pkg/kube/translation/ingress_test.go |  28 ++++-----
 pkg/kube/translation/translator.go   |  14 +++--
 4 files changed, 109 insertions(+), 44 deletions(-)

diff --git a/pkg/ingress/ingress.go b/pkg/ingress/ingress.go
index 4c6d5fe4..1fbad1f9 100644
--- a/pkg/ingress/ingress.go
+++ b/pkg/ingress/ingress.go
@@ -162,7 +162,10 @@ func (c *ingressController) sync(ctx context.Context, ev 
*types.Event) error {
        } else if ev.Type == types.EventAdd {
                added = m
        } else {
-               oldCtx, err := 
c.controller.translator.TranslateIngress(ingEv.OldObject)
+               // In the update event, there is no need to verify the upstream 
in the old ingress,
+               // and the update is based on the latest ingress
+               // TODO There may be residual upstream data. When the service 
is deleted, it has no impact
+               oldCtx, err := 
c.controller.translator.TranslateIngress(ingEv.OldObject, true)
                if err != nil {
                        log.Errorw("failed to translate ingress",
                                zap.String("event", "update"),
diff --git a/pkg/kube/translation/ingress.go b/pkg/kube/translation/ingress.go
index 39a4e452..76fb1e07 100644
--- a/pkg/kube/translation/ingress.go
+++ b/pkg/kube/translation/ingress.go
@@ -39,7 +39,7 @@ const (
        _regexPriority = 100
 )
 
-func (t *translator) translateIngressV1(ing *networkingv1.Ingress) 
(*TranslateContext, error) {
+func (t *translator) translateIngressV1(ing *networkingv1.Ingress, skipVerify 
bool) (*TranslateContext, error) {
        ctx := DefaultEmptyTranslateContext()
        plugins := t.translateAnnotations(ing.Annotations)
        annoExtractor := annotations.NewExtractor(ing.Annotations)
@@ -82,13 +82,17 @@ func (t *translator) translateIngressV1(ing 
*networkingv1.Ingress) (*TranslateCo
                                err          error
                        )
                        if pathRule.Backend.Service != nil {
-                               ups, err = 
t.translateUpstreamFromIngressV1(ing.Namespace, pathRule.Backend.Service)
-                               if err != nil {
-                                       log.Errorw("failed to translate ingress 
backend to upstream",
-                                               zap.Error(err),
-                                               zap.Any("ingress", ing),
-                                       )
-                                       return nil, err
+                               if skipVerify {
+                                       ups = 
t.translateDefaultUpstreamFromIngressV1(ing.Namespace, pathRule.Backend.Service)
+                               } else {
+                                       ups, err = 
t.translateUpstreamFromIngressV1(ing.Namespace, pathRule.Backend.Service)
+                                       if err != nil {
+                                               log.Errorw("failed to translate 
ingress backend to upstream",
+                                                       zap.Error(err),
+                                                       zap.Any("ingress", ing),
+                                               )
+                                               return nil, err
+                                       }
                                }
                                ctx.AddUpstream(ups)
                        }
@@ -156,7 +160,7 @@ func (t *translator) translateIngressV1(ing 
*networkingv1.Ingress) (*TranslateCo
        return ctx, nil
 }
 
-func (t *translator) translateIngressV1beta1(ing *networkingv1beta1.Ingress) 
(*TranslateContext, error) {
+func (t *translator) translateIngressV1beta1(ing *networkingv1beta1.Ingress, 
skipVerify bool) (*TranslateContext, error) {
        ctx := DefaultEmptyTranslateContext()
        plugins := t.translateAnnotations(ing.Annotations)
        annoExtractor := annotations.NewExtractor(ing.Annotations)
@@ -199,13 +203,17 @@ func (t *translator) translateIngressV1beta1(ing 
*networkingv1beta1.Ingress) (*T
                                err          error
                        )
                        if pathRule.Backend.ServiceName != "" {
-                               ups, err = 
t.translateUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
-                               if err != nil {
-                                       log.Errorw("failed to translate ingress 
backend to upstream",
-                                               zap.Error(err),
-                                               zap.Any("ingress", ing),
-                                       )
-                                       return nil, err
+                               if skipVerify {
+                                       ups = 
t.translateDefaultUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+                               } else {
+                                       ups, err = 
t.translateUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+                                       if err != nil {
+                                               log.Errorw("failed to translate 
ingress backend to upstream",
+                                                       zap.Error(err),
+                                                       zap.Any("ingress", ing),
+                                               )
+                                               return nil, err
+                                       }
                                }
                                ctx.AddUpstream(ups)
                        }
@@ -273,6 +281,29 @@ func (t *translator) translateIngressV1beta1(ing 
*networkingv1beta1.Ingress) (*T
        return ctx, nil
 }
 
+func (t *translator) translateDefaultUpstreamFromIngressV1(namespace string, 
backend *networkingv1.IngressServiceBackend) *apisixv1.Upstream {
+       var portNumber int32
+       if backend.Port.Name != "" {
+               svc, err := 
t.ServiceLister.Services(namespace).Get(backend.Name)
+               if err != nil {
+                       portNumber = 0
+               } else {
+                       for _, port := range svc.Spec.Ports {
+                               if port.Name == backend.Port.Name {
+                                       portNumber = port.Port
+                                       break
+                               }
+                       }
+               }
+
+       } else {
+               portNumber = backend.Port.Number
+       }
+       ups := apisixv1.NewDefaultUpstream()
+       ups.Name = apisixv1.ComposeUpstreamName(namespace, backend.Name, "", 
portNumber)
+       ups.ID = id.GenID(ups.Name)
+       return ups
+}
 func (t *translator) translateUpstreamFromIngressV1(namespace string, backend 
*networkingv1.IngressServiceBackend) (*apisixv1.Upstream, error) {
        var svcPort int32
        if backend.Port.Name != "" {
@@ -304,7 +335,7 @@ func (t *translator) 
translateUpstreamFromIngressV1(namespace string, backend *n
        return ups, nil
 }
 
-func (t *translator) translateIngressExtensionsV1beta1(ing 
*extensionsv1beta1.Ingress) (*TranslateContext, error) {
+func (t *translator) translateIngressExtensionsV1beta1(ing 
*extensionsv1beta1.Ingress, skipVerify bool) (*TranslateContext, error) {
        ctx := DefaultEmptyTranslateContext()
        plugins := t.translateAnnotations(ing.Annotations)
        annoExtractor := annotations.NewExtractor(ing.Annotations)
@@ -319,13 +350,17 @@ func (t *translator) 
translateIngressExtensionsV1beta1(ing *extensionsv1beta1.In
                        )
                        if pathRule.Backend.ServiceName != "" {
                                // Structure here is same to 
ingress.extensions/v1beta1, so just use this method.
-                               ups, err = 
t.translateUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
-                               if err != nil {
-                                       log.Errorw("failed to translate ingress 
backend to upstream",
-                                               zap.Error(err),
-                                               zap.Any("ingress", ing),
-                                       )
-                                       return nil, err
+                               if skipVerify {
+                                       ups = 
t.translateDefaultUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+                               } else {
+                                       ups, err = 
t.translateUpstreamFromIngressV1beta1(ing.Namespace, 
pathRule.Backend.ServiceName, pathRule.Backend.ServicePort)
+                                       if err != nil {
+                                               log.Errorw("failed to translate 
ingress backend to upstream",
+                                                       zap.Error(err),
+                                                       zap.Any("ingress", ing),
+                                               )
+                                               return nil, err
+                                       }
                                }
                                ctx.AddUpstream(ups)
                        }
@@ -393,6 +428,29 @@ func (t *translator) translateIngressExtensionsV1beta1(ing 
*extensionsv1beta1.In
        return ctx, nil
 }
 
+func (t *translator) translateDefaultUpstreamFromIngressV1beta1(namespace 
string, svcName string, svcPort intstr.IntOrString) *apisixv1.Upstream {
+       var portNumber int32
+       if svcPort.Type == intstr.String {
+               svc, err := t.ServiceLister.Services(namespace).Get(svcName)
+               if err != nil {
+                       portNumber = 0
+               } else {
+                       for _, port := range svc.Spec.Ports {
+                               if port.Name == svcPort.StrVal {
+                                       portNumber = port.Port
+                                       break
+                               }
+                       }
+               }
+       } else {
+               portNumber = svcPort.IntVal
+       }
+       ups := apisixv1.NewDefaultUpstream()
+       ups.Name = apisixv1.ComposeUpstreamName(namespace, svcName, "", 
portNumber)
+       ups.ID = id.GenID(ups.Name)
+       return ups
+}
+
 func (t *translator) translateUpstreamFromIngressV1beta1(namespace string, 
svcName string, svcPort intstr.IntOrString) (*apisixv1.Upstream, error) {
        var portNumber int32
        if svcPort.Type == intstr.String {
diff --git a/pkg/kube/translation/ingress_test.go 
b/pkg/kube/translation/ingress_test.go
index 4ef25e10..a2365c66 100644
--- a/pkg/kube/translation/ingress_test.go
+++ b/pkg/kube/translation/ingress_test.go
@@ -121,7 +121,7 @@ func TestTranslateIngressV1NoBackend(t *testing.T) {
                },
        }
        tr := &translator{}
-       ctx, err := tr.translateIngressV1(ing)
+       ctx, err := tr.translateIngressV1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 1)
        assert.Len(t, ctx.Upstreams, 0)
@@ -174,7 +174,7 @@ func TestTranslateIngressV1BackendWithInvalidService(t 
*testing.T) {
                        ServiceLister: svcLister,
                },
        }
-       ctx, err := tr.translateIngressV1(ing)
+       ctx, err := tr.translateIngressV1(ing, false)
        assert.NotNil(t, err)
        assert.Nil(t, ctx)
        assert.Equal(t, "service \"test-service\" not found", err.Error())
@@ -197,7 +197,7 @@ func TestTranslateIngressV1BackendWithInvalidService(t 
*testing.T) {
        assert.Nil(t, err)
 
        <-processCh
-       ctx, err = tr.translateIngressV1(ing)
+       ctx, err = tr.translateIngressV1(ing, false)
        assert.Nil(t, ctx, nil)
        assert.Equal(t, &translateError{
                field:  "service",
@@ -282,7 +282,7 @@ func TestTranslateIngressV1WithRegex(t *testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressV1(ing)
+       ctx, err := tr.translateIngressV1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 1)
        assert.Len(t, ctx.Upstreams, 1)
@@ -393,7 +393,7 @@ func TestTranslateIngressV1(t *testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressV1(ing)
+       ctx, err := tr.translateIngressV1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 2)
        assert.Len(t, ctx.Upstreams, 2)
@@ -455,7 +455,7 @@ func TestTranslateIngressV1beta1NoBackend(t *testing.T) {
                },
        }
        tr := &translator{}
-       ctx, err := tr.translateIngressV1beta1(ing)
+       ctx, err := tr.translateIngressV1beta1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 1)
        assert.Len(t, ctx.Upstreams, 0)
@@ -507,7 +507,7 @@ func TestTranslateIngressV1beta1BackendWithInvalidService(t 
*testing.T) {
                        ServiceLister: svcLister,
                },
        }
-       ctx, err := tr.translateIngressV1beta1(ing)
+       ctx, err := tr.translateIngressV1beta1(ing, false)
        assert.NotNil(t, err)
        assert.Nil(t, ctx)
        assert.Equal(t, "service \"test-service\" not found", err.Error())
@@ -530,7 +530,7 @@ func TestTranslateIngressV1beta1BackendWithInvalidService(t 
*testing.T) {
        assert.Nil(t, err)
 
        <-processCh
-       ctx, err = tr.translateIngressV1beta1(ing)
+       ctx, err = tr.translateIngressV1beta1(ing, false)
        assert.Nil(t, ctx)
        assert.Equal(t, &translateError{
                field:  "service",
@@ -615,7 +615,7 @@ func TestTranslateIngressV1beta1WithRegex(t *testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressV1beta1(ing)
+       ctx, err := tr.translateIngressV1beta1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 1)
        assert.Len(t, ctx.Upstreams, 1)
@@ -724,7 +724,7 @@ func TestTranslateIngressV1beta1(t *testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressV1beta1(ing)
+       ctx, err := tr.translateIngressV1beta1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 2)
        assert.Len(t, ctx.Upstreams, 2)
@@ -846,7 +846,7 @@ func TestTranslateIngressExtensionsV1beta1(t *testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressExtensionsV1beta1(ing)
+       ctx, err := tr.translateIngressExtensionsV1beta1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 2)
        assert.Len(t, ctx.Upstreams, 2)
@@ -921,7 +921,7 @@ func 
TestTranslateIngressExtensionsV1beta1BackendWithInvalidService(t *testing.T
                        ServiceLister: svcLister,
                },
        }
-       ctx, err := tr.translateIngressExtensionsV1beta1(ing)
+       ctx, err := tr.translateIngressExtensionsV1beta1(ing, false)
        assert.Nil(t, ctx)
        assert.NotNil(t, err)
        assert.Equal(t, "service \"test-service\" not found", err.Error())
@@ -944,7 +944,7 @@ func 
TestTranslateIngressExtensionsV1beta1BackendWithInvalidService(t *testing.T
        assert.Nil(t, err)
 
        <-processCh
-       ctx, err = tr.translateIngressExtensionsV1beta1(ing)
+       ctx, err = tr.translateIngressExtensionsV1beta1(ing, false)
        assert.Nil(t, ctx)
        assert.Equal(t, &translateError{
                field:  "service",
@@ -1028,7 +1028,7 @@ func TestTranslateIngressExtensionsV1beta1WithRegex(t 
*testing.T) {
 
        <-processCh
        <-processCh
-       ctx, err := tr.translateIngressExtensionsV1beta1(ing)
+       ctx, err := tr.translateIngressExtensionsV1beta1(ing, false)
        assert.Nil(t, err)
        assert.Len(t, ctx.Routes, 1)
        assert.Len(t, ctx.Upstreams, 1)
diff --git a/pkg/kube/translation/translator.go 
b/pkg/kube/translation/translator.go
index 59b3b1bd..418e0fc5 100644
--- a/pkg/kube/translation/translator.go
+++ b/pkg/kube/translation/translator.go
@@ -66,7 +66,7 @@ type Translator interface {
        TranslateUpstream(string, string, string, int32) (*apisixv1.Upstream, 
error)
        // TranslateIngress composes a couple of APISIX Routes and upstreams 
according
        // to the given Ingress resource.
-       TranslateIngress(kube.Ingress) (*TranslateContext, error)
+       TranslateIngress(kube.Ingress, ...bool) (*TranslateContext, error)
        // TranslateRouteV2beta2 translates the configv2beta2.ApisixRoute 
object into several Route,
        // and Upstream resources.
        TranslateRouteV2beta2(*configv2beta2.ApisixRoute) (*TranslateContext, 
error)
@@ -277,14 +277,18 @@ func (t *translator) TranslateUpstreamNodes(endpoint 
kube.Endpoint, port int32,
        return nodes, nil
 }
 
-func (t *translator) TranslateIngress(ing kube.Ingress) (*TranslateContext, 
error) {
+func (t *translator) TranslateIngress(ing kube.Ingress, args ...bool) 
(*TranslateContext, error) {
+       var skipVerify = false
+       if len(args) != 0 {
+               skipVerify = args[0]
+       }
        switch ing.GroupVersion() {
        case kube.IngressV1:
-               return t.translateIngressV1(ing.V1())
+               return t.translateIngressV1(ing.V1(), skipVerify)
        case kube.IngressV1beta1:
-               return t.translateIngressV1beta1(ing.V1beta1())
+               return t.translateIngressV1beta1(ing.V1beta1(), skipVerify)
        case kube.IngressExtensionsV1beta1:
-               return 
t.translateIngressExtensionsV1beta1(ing.ExtensionsV1beta1())
+               return 
t.translateIngressExtensionsV1beta1(ing.ExtensionsV1beta1(), skipVerify)
        default:
                return nil, fmt.Errorf("translator: source group version not 
supported: %s", ing.GroupVersion())
        }

Reply via email to