From b5708436aeae389a98fb649db5b8cf6844f2058d Mon Sep 17 00:00:00 2001 From: Sarasa Kisaragi Date: Fri, 31 Mar 2023 11:30:15 +0800 Subject: [PATCH] fix: Ingress delete events can be handler after svc be deleted (#1576) (#1755) Co-authored-by: fabriceli Co-authored-by: Fabriceli --- pkg/providers/ingress/ingress.go | 7 +++- .../ingress/translation/translator.go | 16 ++++++++ .../suite-ingress-resource/ingress.go | 37 +++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/pkg/providers/ingress/ingress.go b/pkg/providers/ingress/ingress.go index e82aa41a42..f75daba341 100644 --- a/pkg/providers/ingress/ingress.go +++ b/pkg/providers/ingress/ingress.go @@ -142,8 +142,13 @@ func (c *ingressController) sync(ctx context.Context, ev *types.Event) error { } ing = ev.Tombstone.(kube.Ingress) } + var tctx *translation.TranslateContext + if ev.Type == types.EventDelete { + tctx, err = c.translator.TranslateIngressDeleteEvent(ing) + } else { + tctx, err = c.translator.TranslateIngress(ing) + } - tctx, err := c.translator.TranslateIngress(ing) if err != nil { log.Errorw("failed to translate ingress", zap.Error(err), diff --git a/pkg/providers/ingress/translation/translator.go b/pkg/providers/ingress/translation/translator.go index 4a6e05ff14..a4307860d3 100644 --- a/pkg/providers/ingress/translation/translator.go +++ b/pkg/providers/ingress/translation/translator.go @@ -65,6 +65,9 @@ type IngressTranslator interface { TranslateOldIngress(kube.Ingress) (*translation.TranslateContext, error) // TranslateSSLV2 translate networkingv1.IngressTLS to APISIX SSL TranslateIngressTLS(namespace, ingName, secretName string, hosts []string) (*apisixv1.Ssl, error) + // TranslateIngressDeleteEvent composes a couple of APISIX Routes and upstreams according + // to the given Ingress resource. + TranslateIngressDeleteEvent(ing kube.Ingress, args ...bool) (*translation.TranslateContext, error) } func NewIngressTranslator(opts *TranslatorOptions, @@ -119,6 +122,19 @@ func (t *translator) TranslateIngress(ing kube.Ingress, args ...bool) (*translat } } +func (t *translator) TranslateIngressDeleteEvent(ing kube.Ingress, args ...bool) (*translation.TranslateContext, error) { + switch ing.GroupVersion() { + case kube.IngressV1: + return t.translateOldIngressV1(ing.V1()) + case kube.IngressV1beta1: + return t.translateOldIngressV1beta1(ing.V1beta1()) + case kube.IngressExtensionsV1beta1: + return t.translateOldIngressExtensionsv1beta1(ing.ExtensionsV1beta1()) + default: + return nil, fmt.Errorf("translator: source group version not supported: %s", ing.GroupVersion()) + } +} + const ( _regexPriority = 100 ) diff --git a/test/e2e/suite-ingress/suite-ingress-resource/ingress.go b/test/e2e/suite-ingress/suite-ingress-resource/ingress.go index 1c6eda7968..3f32f682ce 100644 --- a/test/e2e/suite-ingress/suite-ingress-resource/ingress.go +++ b/test/e2e/suite-ingress/suite-ingress-resource/ingress.go @@ -792,3 +792,40 @@ spec: _ = s.NewAPISIXClient().GET("/anything/aaa/ok").WithHeader("Host", "a.httpbin.org").Expect().Status(http.StatusNotFound) }) }) + +var _ = ginkgo.Describe("suite-ingress-resource: svc delete", func() { + s := scaffold.NewDefaultScaffold() + ginkgo.It("svc delete before ing delete", func() { + backendSvc, backendSvcPort := s.DefaultHTTPBackend() + ing := fmt.Sprintf(` +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: httpbin-route +spec: + ingressClassName: apisix + rules: + - host: httpbin.com + http: + paths: + - path: /ip + pathType: Exact + backend: + service: + name: %s + port: + number: %d +`, backendSvc, backendSvcPort[0]) + assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ing)) + assert.Nil(ginkgo.GinkgoT(), s.EnsureNumListUpstreamNodesNth(1, 1)) + + // Now delete the backend httpbin service resource. + assert.Nil(ginkgo.GinkgoT(), s.DeleteHTTPBINService()) + assert.Nil(ginkgo.GinkgoT(), s.EnsureNumListUpstreamNodesNth(1, 0)) + s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusServiceUnavailable) + + assert.Nil(ginkgo.GinkgoT(), s.DeleteResourceFromString(ing)) + s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.com").Expect().Status(http.StatusNotFound) + + }) +})