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 af0dec4  fix: handle upstream caching delete correctly (#422)
af0dec4 is described below

commit af0dec4f12dd5f2edacee4184d5190d745bc497d
Author: Alex Zhang <[email protected]>
AuthorDate: Sat May 8 13:47:22 2021 +0800

    fix: handle upstream caching delete correctly (#422)
---
 pkg/ingress/manifest.go             |  21 ++++++--
 test/e2e/ingress/resourcepushing.go | 102 ++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/pkg/ingress/manifest.go b/pkg/ingress/manifest.go
index 42cfb61..d597714 100644
--- a/pkg/ingress/manifest.go
+++ b/pkg/ingress/manifest.go
@@ -19,7 +19,10 @@ import (
        "reflect"
 
        "github.com/hashicorp/go-multierror"
+       "go.uber.org/zap"
 
+       "github.com/apache/apisix-ingress-controller/pkg/apisix/cache"
+       "github.com/apache/apisix-ingress-controller/pkg/log"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
 
@@ -149,16 +152,24 @@ func (c *Controller) syncManifests(ctx context.Context, 
added, updated, deleted
                                merr = multierror.Append(merr, err)
                        }
                }
-               for _, u := range deleted.upstreams {
-                       if err := 
c.apisix.Cluster(clusterName).Upstream().Delete(ctx, u); err != nil {
-                               merr = multierror.Append(merr, err)
-                       }
-               }
                for _, sr := range deleted.streamRoutes {
                        if err := 
c.apisix.Cluster(clusterName).StreamRoute().Delete(ctx, sr); err != nil {
                                merr = multierror.Append(merr, err)
                        }
                }
+               for _, u := range deleted.upstreams {
+                       if err := 
c.apisix.Cluster(clusterName).Upstream().Delete(ctx, u); err != nil {
+                               // Upstream might be referenced by other routes.
+                               if err != cache.ErrStillInUse {
+                                       merr = multierror.Append(merr, err)
+                               } else {
+                                       log.Infow("upstream was referenced by 
other routes",
+                                               zap.String("upstream_id", u.ID),
+                                               zap.String("upstream_name", 
u.Name),
+                                       )
+                               }
+                       }
+               }
        }
        if added != nil {
                // Should create upstreams firstly due to the dependencies.
diff --git a/test/e2e/ingress/resourcepushing.go 
b/test/e2e/ingress/resourcepushing.go
index 99e201c..2c459fc 100644
--- a/test/e2e/ingress/resourcepushing.go
+++ b/test/e2e/ingress/resourcepushing.go
@@ -389,4 +389,106 @@ spec:
                resp.Status(http.StatusNotFound)
                resp.Body().Contains("404 Route Not Found")
        })
+
+       ginkgo.It("service is referenced by two ApisixRoutes", func() {
+               backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+               ar1 := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+  name: httpbin-route-1
+spec:
+  http:
+  - name: rule1
+    priority: 1
+    match:
+      hosts:
+      - httpbin.com
+      paths:
+      - /ip
+    backend:
+      serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+               ar2 := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+  name: httpbin-route-2
+spec:
+  http:
+  - name: rule1
+    priority: 1
+    match:
+      hosts:
+      - httpbin.com
+      paths:
+      - /status/200
+    backend:
+      serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+               err := s.CreateResourceFromString(ar1)
+               assert.Nil(ginkgo.GinkgoT(), err)
+               err = s.CreateResourceFromString(ar2)
+               assert.Nil(ginkgo.GinkgoT(), err)
+
+               time.Sleep(3 * time.Second)
+
+               routes, err := s.ListApisixRoutes()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing routes")
+               assert.Len(ginkgo.GinkgoT(), routes, 2)
+
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing upstreams")
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].ID, routes[0].UpstreamId)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].ID, routes[1].UpstreamId)
+
+               resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.com").Expect()
+               resp.Status(http.StatusOK)
+               resp.Body().Contains("origin")
+
+               resp = 
s.NewAPISIXClient().GET("/status/200").WithHeader("Host", 
"httpbin.com").Expect()
+               resp.Status(http.StatusOK)
+
+               // Delete ar1
+               err = s.RemoveResourceByString(ar1)
+               assert.Nil(ginkgo.GinkgoT(), err)
+               time.Sleep(3 * time.Second)
+
+               routes, err = s.ListApisixRoutes()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing routes")
+               assert.Len(ginkgo.GinkgoT(), routes, 1)
+               name := s.Namespace() + "_" + "httpbin-route-2" + "_" + "rule1"
+               assert.Equal(ginkgo.GinkgoT(), routes[0].Name, name)
+
+               // As httpbin service is referenced by ar2, the corresponding 
upstream still exists.
+               ups, err = s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing upstreams")
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), ups[0].ID, routes[0].UpstreamId)
+
+               resp = s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.com").Expect()
+               resp.Status(http.StatusNotFound)
+               resp = 
s.NewAPISIXClient().GET("/status/200").WithHeader("Host", 
"httpbin.com").Expect()
+               resp.Status(http.StatusOK)
+
+               // Delete ar2
+               err = s.RemoveResourceByString(ar2)
+               assert.Nil(ginkgo.GinkgoT(), err)
+               time.Sleep(3 * time.Second)
+
+               routes, err = s.ListApisixRoutes()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing routes")
+               assert.Len(ginkgo.GinkgoT(), routes, 0)
+
+               ups, err = s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err, "listing upstreams")
+               assert.Len(ginkgo.GinkgoT(), ups, 0)
+
+               resp = 
s.NewAPISIXClient().GET("/status/200").WithHeader("Host", 
"httpbin.com").Expect()
+               resp.Status(http.StatusNotFound)
+       })
 })

Reply via email to