This is an automated email from the ASF dual-hosted git repository.
kvn 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 806f2f8 fix: ApisixRoute update operations is not effective (#319)
806f2f8 is described below
commit 806f2f8c2a54a87e6540620e88791c4409424382
Author: Alex Zhang <[email protected]>
AuthorDate: Wed Mar 31 19:19:19 2021 +0800
fix: ApisixRoute update operations is not effective (#319)
* fix: ApisixRoute update operations is not effective
* fix
* test: add two more e2e test cases about apisixroute
---
go.mod | 1 +
go.sum | 44 +-----
pkg/ingress/controller/apisix_route.go | 60 ++++++---
pkg/ingress/controller/endpoint.go | 24 ++--
pkg/ingress/controller/ingress.go | 43 ++++--
pkg/ingress/controller/manifest.go | 155 +++++++++++++++++++++
pkg/ingress/controller/manifest_test.go | 190 ++++++++++++++++++++++++++
pkg/kube/ingress.go | 1 +
pkg/kube/translation/apisix_route.go | 1 +
pkg/seven/state/builder.go | 231 --------------------------------
pkg/seven/state/builder_test.go | 51 -------
pkg/seven/state/event.go | 34 +----
pkg/seven/state/route_worker.go | 68 ----------
pkg/seven/state/solver.go | 184 -------------------------
test/e2e/ingress/resourcepushing.go | 173 +++++++++++++++++++++++-
15 files changed, 608 insertions(+), 652 deletions(-)
diff --git a/go.mod b/go.mod
index 99be1b7..59dffa4 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
github.com/gin-gonic/gin v1.6.3
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/hashicorp/go-memdb v1.0.4
+ github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 //
indirect
diff --git a/go.sum b/go.sum
index d0cf595..6b48ff8 100644
--- a/go.sum
+++ b/go.sum
@@ -8,7 +8,6 @@ cloud.google.com/go v0.46.3/go.mod
h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg
cloud.google.com/go v0.50.0/go.mod
h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod
h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod
h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0=
cloud.google.com/go v0.54.0/go.mod
h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go/bigquery v1.0.1/go.mod
h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod
h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@@ -48,7 +47,6 @@ github.com/armon/go-metrics
v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod
h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod
h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod
h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod
h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod
h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -68,7 +66,6 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod
h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-semver v0.3.0/go.mod
h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod
h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod
h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man/v2 v2.0.0
h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod
h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -85,7 +82,6 @@ github.com/evanphx/json-patch v4.9.0+incompatible
h1:kLcOMZeuLAJvL2BPWLMIj5oaZQo
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod
h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod
h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod
h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/fsnotify/fsnotify v1.4.7
h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod
h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9
h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod
h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -127,7 +123,6 @@ github.com/gogo/protobuf v1.3.1
h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod
h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod
h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef
h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod
h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod
h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod
h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -140,9 +135,7 @@ github.com/golang/mock v1.4.0/go.mod
h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod
h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod
h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod
h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2
h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod
h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3
h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod
h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod
h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod
h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
@@ -157,14 +150,12 @@ github.com/golang/protobuf v1.4.3/go.mod
h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod
h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod
h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod
h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -183,7 +174,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod
h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/gnostic v0.4.1
h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
github.com/googleapis/gnostic v0.4.1/go.mod
h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod
h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/websocket v1.4.2
h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod
h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod
h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod
h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@@ -200,6 +190,7 @@ github.com/hashicorp/go-immutable-radix v1.1.0/go.mod
h1:0y9vanUI8NX6FsYoO3zeMjh
github.com/hashicorp/go-memdb v1.0.4
h1:sIdJHAEtV3//iXcUb4LumSQeorYos5V0ptvqvQvFgDA=
github.com/hashicorp/go-memdb v1.0.4/go.mod
h1:LWQ8R70vPrS4OEY9k28D2z8/Zzyu34NVzeRibGAzHO0=
github.com/hashicorp/go-msgpack v0.5.3/go.mod
h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0
h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod
h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod
h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod
h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
@@ -209,7 +200,6 @@ github.com/hashicorp/go-uuid v1.0.1
h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1
github.com/hashicorp/go-uuid v1.0.1/go.mod
h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod
h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod
h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1
h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod
h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3
h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod
h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
@@ -221,7 +211,6 @@ github.com/hashicorp/serf v0.8.2/go.mod
h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod
h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod
h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod
h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.11
h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod
h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
@@ -229,7 +218,6 @@ github.com/inconshreveable/mousetrap v1.0.0
h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod
h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod
h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod
h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.9
h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod
h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10
h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod
h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -244,7 +232,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod
h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/gotool v1.0.0/go.mod
h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod
h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod
h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod
h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod
h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -264,14 +251,12 @@ github.com/mattn/go-isatty v0.0.3/go.mod
h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.8/go.mod
h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12
h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod
h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1
h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod
h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions
v1.0.2-0.20181231171920-c182affec369
h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions
v1.0.2-0.20181231171920-c182affec369/go.mod
h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod
h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod
h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-homedir v1.1.0
h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod
h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod
h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
@@ -300,7 +285,6 @@ github.com/pascaldekloe/goe
v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pelletier/go-toml v1.2.0/go.mod
h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod
h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -308,26 +292,21 @@ github.com/pmezard/go-difflib v1.0.0
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod
h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod
h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.3
h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
github.com/prometheus/client_golang v0.9.3/go.mod
h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod
h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1
h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
github.com/prometheus/client_golang v1.7.1/go.mod
h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod
h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4
h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0
h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod
h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.0
h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0
h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
github.com/prometheus/common v0.10.0/go.mod
h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod
h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084
h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod
h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod
h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod
h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
@@ -336,13 +315,11 @@ github.com/prometheus/procfs v0.2.0/go.mod
h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/tsdb v0.7.1/go.mod
h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod
h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod
h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/russross/blackfriday/v2 v2.0.1
h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod
h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod
h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod
h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod
h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0
h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod
h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod
h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod
h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -366,7 +343,6 @@ github.com/stretchr/objx v0.1.1/go.mod
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod
h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod
h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod
h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0
h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod
h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1
h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -404,11 +380,9 @@ golang.org/x/crypto
v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod
h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -430,7 +404,6 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod
h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod
h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod
h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod
h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de
h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod
h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod
h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod
h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
@@ -442,7 +415,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod
h1:mXi4GBBbnImb6dmsKG
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -476,7 +448,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b
h1:iFwSg7t5GZmB/Q5TjiEAsdoLD
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod
h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
@@ -511,7 +482,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod
h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42
h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -528,14 +498,11 @@ golang.org/x/term
v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
@@ -561,7 +528,6 @@ golang.org/x/tools
v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc
h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -577,11 +543,9 @@ golang.org/x/tools
v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb
h1:iKlO7ROJc6SttHKlxzwGytRtBUqX4VARrNTgP2YLX5M=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod
h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054
h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod
h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -600,7 +564,6 @@ google.golang.org/api v0.20.0/go.mod
h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/appengine v1.1.0/go.mod
h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod
h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod
h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1
h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod
h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5
h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod
h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
@@ -622,7 +585,6 @@ google.golang.org/genproto
v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod
h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod
h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod
h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod
h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod
h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod
h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -630,7 +592,6 @@ google.golang.org/grpc v1.21.1/go.mod
h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
google.golang.org/grpc v1.23.0/go.mod
h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0/go.mod
h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod
h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod
h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod
h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod
h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -662,7 +623,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod
h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -672,7 +632,6 @@ honnef.co/go/tools
v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod
h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod
h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod
h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3
h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod
h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3
h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod
h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
@@ -695,7 +654,6 @@ rsc.io/quote/v3 v3.1.0/go.mod
h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2
h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod
h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/pkg/ingress/controller/apisix_route.go
b/pkg/ingress/controller/apisix_route.go
index d8fcb99..36aded8 100644
--- a/pkg/ingress/controller/apisix_route.go
+++ b/pkg/ingress/controller/apisix_route.go
@@ -25,7 +25,6 @@ import (
"github.com/apache/apisix-ingress-controller/pkg/kube"
"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"
)
@@ -154,33 +153,48 @@ func (c *apisixRouteController) sync(ctx context.Context,
ev *types.Event) error
zap.Any("apisix_route", ar),
)
+ m := &manifest{
+ routes: routes,
+ upstreams: upstreams,
+ }
+
+ var (
+ added *manifest
+ updated *manifest
+ deleted *manifest
+ )
+
if ev.Type == types.EventDelete {
- rc := &state.RouteCompare{OldRoutes: routes, NewRoutes: nil}
- if err := rc.Sync(); err != nil {
- return err
- } else {
- comb := state.ApisixCombination{Routes: nil, Upstreams:
upstreams}
- if err := comb.Remove(); err != nil {
- return err
- }
- }
- return nil
+ deleted = m
} else if ev.Type == types.EventAdd {
- comb := state.ApisixCombination{Routes: routes, Upstreams:
upstreams}
- if _, err := comb.Solver(); err != nil {
- return err
- }
+ added = m
} else {
- var oldRoutes []*apisixv1.Route
+ var (
+ oldRoutes []*apisixv1.Route
+ oldUpstreams []*apisixv1.Upstream
+ )
if obj.GroupVersion == kube.ApisixRouteV1 {
- oldRoutes, _, _ =
c.controller.translator.TranslateRouteV1(ar.V1())
+ oldRoutes, oldUpstreams, err =
c.controller.translator.TranslateRouteV1(obj.OldObject.V1())
} else {
- oldRoutes, _, _ =
c.controller.translator.TranslateRouteV2alpha1(ar.V2alpha1())
+ oldRoutes, oldUpstreams, err =
c.controller.translator.TranslateRouteV2alpha1(obj.OldObject.V2alpha1())
}
- rc := &state.RouteCompare{OldRoutes: oldRoutes, NewRoutes:
routes}
- return rc.Sync()
+ if err != nil {
+ log.Errorw("failed to translate old ApisixRoute
v2alpha1",
+ zap.String("event", "update"),
+ zap.Error(err),
+ zap.Any("ApisixRoute", ar),
+ )
+ return err
+ }
+
+ om := &manifest{
+ routes: oldRoutes,
+ upstreams: oldUpstreams,
+ }
+ added, updated, deleted = m.diff(om)
}
- return nil
+
+ return c.controller.syncManifests(ctx, added, updated, deleted)
}
func (c *apisixRouteController) handleSyncErr(obj interface{}, err error) {
@@ -231,6 +245,10 @@ func (c *apisixRouteController) onUpdate(oldObj, newObj
interface{}) {
if !c.controller.namespaceWatching(key) {
return
}
+ log.Debugw("ApisixRoute update event arrived",
+ zap.Any("new object", curr),
+ zap.Any("old object", prev),
+ )
c.workqueue.AddRateLimited(&types.Event{
Type: types.EventUpdate,
Object: kube.ApisixRouteEvent{
diff --git a/pkg/ingress/controller/endpoint.go
b/pkg/ingress/controller/endpoint.go
index 62bed20..ad22a36 100644
--- a/pkg/ingress/controller/endpoint.go
+++ b/pkg/ingress/controller/endpoint.go
@@ -27,7 +27,6 @@ import (
"github.com/apache/apisix-ingress-controller/pkg/apisix"
apisixcache
"github.com/apache/apisix-ingress-controller/pkg/apisix/cache"
"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"
)
@@ -156,18 +155,10 @@ func (c *endpointsController) syncToCluster(ctx
context.Context, cluster apisix.
zap.String("cluster", cluster.String()),
)
- upstreams := []*apisixv1.Upstream{upstream}
- comb := state.ApisixCombination{Routes: nil, Services: nil, Upstreams:
upstreams}
-
- if _, err = comb.Solver(); err != nil {
- log.Errorw("failed to sync upstream",
- zap.String("upstream", upsName),
- zap.String("cluster", cluster.String()),
- zap.Error(err),
- )
- return err
+ updated := &manifest{
+ upstreams: []*apisixv1.Upstream{upstream},
}
- return nil
+ return c.controller.syncManifests(ctx, nil, updated, nil)
}
func (c *endpointsController) handleSyncErr(obj interface{}, err error) {
@@ -190,6 +181,8 @@ func (c *endpointsController) onAdd(obj interface{}) {
if !c.controller.namespaceWatching(key) {
return
}
+ log.Debugw("endpoints add event arrived",
+ zap.Any("object", obj))
c.workqueue.AddRateLimited(&types.Event{
Type: types.EventAdd,
@@ -212,6 +205,10 @@ func (c *endpointsController) onUpdate(prev, curr
interface{}) {
if !c.controller.namespaceWatching(key) {
return
}
+ log.Debugw("endpoints update event arrived",
+ zap.Any("new object", currEp),
+ zap.Any("old object", prevEp),
+ )
c.workqueue.AddRateLimited(&types.Event{
Type: types.EventUpdate,
Object: curr,
@@ -235,6 +232,9 @@ func (c *endpointsController) onDelete(obj interface{}) {
if !c.controller.namespaceWatching(ep.Namespace + "/" + ep.Name) {
return
}
+ log.Debugw("endpoints delete event arrived",
+ zap.Any("final state", ep),
+ )
c.workqueue.AddRateLimited(&types.Event{
Type: types.EventDelete,
Object: ep,
diff --git a/pkg/ingress/controller/ingress.go
b/pkg/ingress/controller/ingress.go
index f1ac7a9..badc105 100644
--- a/pkg/ingress/controller/ingress.go
+++ b/pkg/ingress/controller/ingress.go
@@ -137,16 +137,42 @@ func (c *ingressController) sync(ctx context.Context, ev
*types.Event) error {
zap.Any("upstreams", upstreams),
)
- if err := c.syncToCluster(ctx, "", routes, upstreams, ev.Type); err !=
nil {
- log.Errorw("failed to sync ingress artifacts (routes,
upstreams)",
- zap.Error(err),
- zap.Any("routes", routes),
- zap.Any("upstreams", upstreams),
- zap.Any("ingress", ing),
+ m := &manifest{
+ routes: routes,
+ upstreams: upstreams,
+ }
+
+ var (
+ added *manifest
+ updated *manifest
+ deleted *manifest
+ )
+
+ if ev.Type == types.EventDelete {
+ deleted = m
+ } else if ev.Type == types.EventAdd {
+ added = m
+ } else {
+ var (
+ oldRoutes []*apisixv1.Route
+ oldUpstreams []*apisixv1.Upstream
)
- return err
+ oldRoutes, oldUpstreams, err :=
c.controller.translator.TranslateIngress(ingEv.OldObject)
+ if err != nil {
+ log.Errorw("failed to translate ingress",
+ zap.String("event", "update"),
+ zap.Error(err),
+ zap.Any("ingress", ingEv.OldObject),
+ )
+ return err
+ }
+ om := &manifest{
+ routes: oldRoutes,
+ upstreams: oldUpstreams,
+ }
+ added, updated, deleted = m.diff(om)
}
- return nil
+ return c.controller.syncManifests(ctx, added, updated, deleted)
}
func (c *ingressController) syncToCluster(ctx context.Context, clusterName
string, routes []*apisixv1.Route, upstreams []*apisixv1.Upstream, ev
types.EventType) error {
@@ -272,6 +298,7 @@ func (c *ingressController) onUpdate(oldObj, newObj
interface{}) {
Object: kube.IngressEvent{
Key: key,
GroupVersion: curr.GroupVersion(),
+ OldObject: prev,
},
})
}
diff --git a/pkg/ingress/controller/manifest.go
b/pkg/ingress/controller/manifest.go
new file mode 100644
index 0000000..709f986
--- /dev/null
+++ b/pkg/ingress/controller/manifest.go
@@ -0,0 +1,155 @@
+// 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 (
+ "context"
+ "reflect"
+
+ "github.com/hashicorp/go-multierror"
+
+ apisixv1
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+)
+
+func diffRoutes(olds, news []*apisixv1.Route) (added, updated, deleted
[]*apisixv1.Route) {
+ if olds == nil {
+ return news, nil, nil
+ }
+ if news == nil {
+ return nil, nil, olds
+ }
+
+ oldMap := make(map[string]*apisixv1.Route, len(olds))
+ newMap := make(map[string]*apisixv1.Route, len(news))
+ for _, r := range olds {
+ oldMap[r.ID] = r
+ }
+ for _, r := range news {
+ newMap[r.ID] = r
+ }
+
+ for _, r := range news {
+ if or, ok := oldMap[r.ID]; !ok {
+ added = append(added, r)
+ } else if !reflect.DeepEqual(or, r) {
+ updated = append(updated, r)
+ }
+ }
+ for _, r := range olds {
+ if _, ok := newMap[r.ID]; !ok {
+ deleted = append(deleted, r)
+ }
+ }
+ return
+}
+
+func diffUpstreams(olds, news []*apisixv1.Upstream) (added, updated, deleted
[]*apisixv1.Upstream) {
+ oldMap := make(map[string]*apisixv1.Upstream, len(olds))
+ newMap := make(map[string]*apisixv1.Upstream, len(news))
+ for _, u := range olds {
+ oldMap[u.ID] = u
+ }
+ for _, u := range news {
+ newMap[u.ID] = u
+ }
+
+ for _, u := range news {
+ if ou, ok := oldMap[u.ID]; !ok {
+ added = append(added, u)
+ } else if !reflect.DeepEqual(ou, u) {
+ updated = append(updated, u)
+ }
+ }
+ for _, u := range olds {
+ if _, ok := newMap[u.ID]; !ok {
+ deleted = append(deleted, u)
+ }
+ }
+ return
+}
+
+type manifest struct {
+ routes []*apisixv1.Route
+ upstreams []*apisixv1.Upstream
+}
+
+func (m *manifest) diff(om *manifest) (added, updated, deleted *manifest) {
+ ar, ur, dr := diffRoutes(om.routes, m.routes)
+ au, uu, du := diffUpstreams(om.upstreams, m.upstreams)
+ if ar != nil || au != nil {
+ added = &manifest{
+ routes: ar,
+ upstreams: au,
+ }
+ }
+ if ur != nil || uu != nil {
+ updated = &manifest{
+ routes: ur,
+ upstreams: uu,
+ }
+ }
+ if dr != nil || du != nil {
+ deleted = &manifest{
+ routes: dr,
+ upstreams: du,
+ }
+ }
+ return
+}
+
+func (c *Controller) syncManifests(ctx context.Context, added, updated,
deleted *manifest) error {
+ var merr *multierror.Error
+ if deleted != nil {
+ for _, r := range deleted.routes {
+ if err := c.apisix.Cluster("").Route().Delete(ctx, r);
err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ for _, u := range deleted.upstreams {
+ if err := c.apisix.Cluster("").Upstream().Delete(ctx,
u); err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ }
+ if added != nil {
+ // Should create upstreams firstly due to the dependencies.
+ for _, u := range added.upstreams {
+ if _, err :=
c.apisix.Cluster("").Upstream().Create(ctx, u); err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ for _, r := range added.routes {
+ if _, err := c.apisix.Cluster("").Route().Create(ctx,
r); err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ }
+ if updated != nil {
+ for _, r := range updated.upstreams {
+ if _, err :=
c.apisix.Cluster("").Upstream().Update(ctx, r); err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ for _, r := range updated.routes {
+ if _, err := c.apisix.Cluster("").Route().Update(ctx,
r); err != nil {
+ merr = multierror.Append(merr, err)
+ }
+ }
+ }
+ if merr != nil {
+ return merr
+ }
+ return nil
+}
diff --git a/pkg/ingress/controller/manifest_test.go
b/pkg/ingress/controller/manifest_test.go
new file mode 100644
index 0000000..811aefc
--- /dev/null
+++ b/pkg/ingress/controller/manifest_test.go
@@ -0,0 +1,190 @@
+// 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 (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ apisixv1
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
+)
+
+func TestDiffRoutes(t *testing.T) {
+ news := []*apisixv1.Route{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "1",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Methods: []string{"POST"},
+ },
+ }
+ added, updated, deleted := diffRoutes(nil, news)
+ assert.Nil(t, updated)
+ assert.Nil(t, deleted)
+ assert.Len(t, added, 2)
+ assert.Equal(t, added[0].ID, "1")
+ assert.Equal(t, added[1].ID, "3")
+ assert.Equal(t, added[1].Methods, []string{"POST"})
+
+ olds := []*apisixv1.Route{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "2",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Methods: []string{"POST", "PUT"},
+ },
+ }
+ added, updated, deleted = diffRoutes(olds, nil)
+ assert.Nil(t, updated)
+ assert.Nil(t, added)
+ assert.Len(t, deleted, 2)
+ assert.Equal(t, deleted[0].ID, "2")
+ assert.Equal(t, deleted[1].ID, "3")
+ assert.Equal(t, deleted[1].Methods, []string{"POST", "PUT"})
+
+ added, updated, deleted = diffRoutes(olds, news)
+ assert.Len(t, added, 1)
+ assert.Equal(t, added[0].ID, "1")
+ assert.Len(t, updated, 1)
+ assert.Equal(t, updated[0].ID, "3")
+ assert.Equal(t, updated[0].Methods, []string{"POST"})
+ assert.Len(t, deleted, 1)
+ assert.Equal(t, deleted[0].ID, "2")
+}
+
+func TestDiffUpstreams(t *testing.T) {
+ news := []*apisixv1.Upstream{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "1",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Retries: 3,
+ },
+ }
+ added, updated, deleted := diffUpstreams(nil, news)
+ assert.Nil(t, updated)
+ assert.Nil(t, deleted)
+ assert.Len(t, added, 2)
+ assert.Equal(t, added[0].ID, "1")
+ assert.Equal(t, added[1].ID, "3")
+ assert.Equal(t, added[1].Retries, 3)
+
+ olds := []*apisixv1.Upstream{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "2",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Retries: 5,
+ Timeout: &apisixv1.UpstreamTimeout{
+ Connect: 10,
+ },
+ },
+ }
+ added, updated, deleted = diffUpstreams(olds, nil)
+ assert.Nil(t, updated)
+ assert.Nil(t, added)
+ assert.Len(t, deleted, 2)
+ assert.Equal(t, deleted[0].ID, "2")
+ assert.Equal(t, deleted[1].ID, "3")
+ assert.Equal(t, deleted[1].Retries, 5)
+ assert.Equal(t, deleted[1].Timeout.Connect, 10)
+
+ added, updated, deleted = diffUpstreams(olds, news)
+ assert.Len(t, added, 1)
+ assert.Equal(t, added[0].ID, "1")
+ assert.Len(t, updated, 1)
+ assert.Equal(t, updated[0].ID, "3")
+ assert.Nil(t, updated[0].Timeout)
+ assert.Equal(t, updated[0].Retries, 3)
+ assert.Len(t, deleted, 1)
+ assert.Equal(t, deleted[0].ID, "2")
+}
+
+func TestManifestDiff(t *testing.T) {
+ m := &manifest{
+ routes: []*apisixv1.Route{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "1",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Methods: []string{"GET"},
+ },
+ },
+ upstreams: []*apisixv1.Upstream{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "4",
+ },
+ Retries: 2,
+ },
+ },
+ }
+ om := &manifest{
+ routes: []*apisixv1.Route{
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "2",
+ },
+ },
+ {
+ Metadata: apisixv1.Metadata{
+ ID: "3",
+ },
+ Methods: []string{"GET", "HEAD"},
+ },
+ },
+ }
+
+ added, updated, deleted := m.diff(om)
+ assert.Len(t, added.routes, 1)
+ assert.Equal(t, added.routes[0].ID, "1")
+ assert.Len(t, added.upstreams, 1)
+ assert.Equal(t, added.upstreams[0].ID, "4")
+
+ assert.Len(t, updated.routes, 1)
+ assert.Equal(t, updated.routes[0].ID, "3")
+ assert.Equal(t, updated.routes[0].Methods, []string{"GET"})
+ assert.Nil(t, updated.upstreams)
+
+ assert.Len(t, deleted.routes, 1)
+ assert.Equal(t, deleted.routes[0].ID, "2")
+ assert.Nil(t, updated.upstreams)
+}
diff --git a/pkg/kube/ingress.go b/pkg/kube/ingress.go
index cd355da..ac39470 100644
--- a/pkg/kube/ingress.go
+++ b/pkg/kube/ingress.go
@@ -76,6 +76,7 @@ type Ingress interface {
type IngressEvent struct {
Key string
GroupVersion string
+ OldObject Ingress
}
type ingress struct {
diff --git a/pkg/kube/translation/apisix_route.go
b/pkg/kube/translation/apisix_route.go
index c3a8b8f..770a040 100644
--- a/pkg/kube/translation/apisix_route.go
+++ b/pkg/kube/translation/apisix_route.go
@@ -62,6 +62,7 @@ func (t *translator) TranslateRouteV1(ar
*configv1.ApisixRoute) ([]*apisixv1.Rou
upsId := id.GenID(upstreamName)
route := &apisixv1.Route{
Metadata: apisixv1.Metadata{
+ ID: id.GenID(routeName),
FullName: routeName,
ResourceVersion: ar.ResourceVersion,
Name: routeName,
diff --git a/pkg/seven/state/builder.go b/pkg/seven/state/builder.go
deleted file mode 100644
index 9265cd9..0000000
--- a/pkg/seven/state/builder.go
+++ /dev/null
@@ -1,231 +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"
- "errors"
- "sync"
-
- "github.com/apache/apisix-ingress-controller/pkg/apisix/cache"
- "github.com/apache/apisix-ingress-controller/pkg/id"
- "github.com/apache/apisix-ingress-controller/pkg/log"
- "github.com/apache/apisix-ingress-controller/pkg/seven/conf"
- "github.com/apache/apisix-ingress-controller/pkg/seven/utils"
- v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-const (
- ApisixUpstream = "ApisixUpstream"
- WatchFromKind = "watch"
-)
-
-// paddingRoute fills route through currentRoute, it returns a boolean
-// value to indicate whether the route is a new created one.
-func paddingRoute(route *v1.Route, currentRoute *v1.Route) bool {
- if currentRoute == nil {
- route.ID = id.GenID(route.FullName)
- return true
- }
- route.ID = currentRoute.ID
- return false
-}
-
-// paddingService fills service through currentService, it returns a boolean
-// value to indicate whether the service is a new created one.
-func paddingService(service *v1.Service, currentService *v1.Service) bool {
- if currentService == nil {
- service.ID = id.GenID(service.FullName)
- return true
- }
- service.ID = currentService.ID
- return false
-}
-
-// paddingUpstream fills upstream through currentUpstream, it returns a boolean
-// value to indicate whether the upstream is a new created one.
-func paddingUpstream(upstream *v1.Upstream, currentUpstream *v1.Upstream) bool
{
- if currentUpstream == nil {
- upstream.ID = id.GenID(upstream.FullName)
- return true
- }
- upstream.ID = currentUpstream.ID
- return false
-}
-
-// NewRouteWorkers make routeWorkers group by service per CRD
-// 1.make routes group by (1_2_3) it may be a map like map[1_2_3][]Route;
-// 2.route is listening Event from the ready of 1_2_3;
-func NewRouteWorkers(ctx context.Context,
- routes []*v1.Route, wg *sync.WaitGroup, errorChan chan CRDStatus)
RouteWorkerGroup {
-
- rwg := make(RouteWorkerGroup)
- for _, r := range routes {
- rw := &routeWorker{Route: r, Ctx: ctx, Wg: wg, ErrorChan:
errorChan}
- rw.start()
- rwg.Add(r.UpstreamName, rw)
- }
- return rwg
-}
-
-// 3.route get the Event and trigger a padding for object,then diff,sync;
-func (r *routeWorker) trigger() {
- var (
- op string
- errNotify error
- )
- defer func() {
- if errNotify != nil {
- r.ErrorChan <- CRDStatus{Id: "", Status: "failure",
Err: errNotify}
- }
- r.Wg.Done()
- }()
-
- // padding
- var cluster string
- if r.Route.Group != "" {
- cluster = r.Route.Group
- }
- currentRoute, err :=
conf.Client.Cluster(cluster).Route().Get(context.TODO(), r.Route.FullName)
- if err != nil && !errors.Is(err, cache.ErrNotFound) {
- errNotify = err
- return
- }
-
- if paddingRoute(r.Route, currentRoute) {
- op = Create
- } else {
- op = Update
- }
-
- hasDiff, err := utils.HasDiff(r.Route, currentRoute)
- if err != nil {
- errNotify = err
- return
- }
- if hasDiff {
- err := r.sync(op)
- if err != nil {
- errNotify = err
- return
- }
- }
-}
-
-// sync
-func (r *routeWorker) sync(op string) error {
- var cluster string
- if r.Group != "" {
- cluster = r.Group
- }
- if op == Update {
- if _, err :=
conf.Client.Cluster(cluster).Route().Update(context.TODO(), r.Route); err !=
nil {
- log.Errorf("failed to update route %s: %s, ", r.Name,
err)
- return err
- }
- log.Infof("update route %s, %s", r.Name, r.ServiceId)
- } else {
- route, err :=
conf.Client.Cluster(cluster).Route().Create(context.TODO(), r.Route)
- if err != nil {
- log.Errorf("failed to create route: %s", err.Error())
- return err
- }
- r.ID = route.ID
- }
- log.Infof("create route %s, %s", r.Name, r.ServiceId)
- return nil
-}
-
-// upstream
-func SolverUpstream(upstreams []*v1.Upstream, rwg RouteWorkerGroup, wg
*sync.WaitGroup, errorChan chan CRDStatus) {
- for _, u := range upstreams {
- go SolverSingleUpstream(u, rwg, wg, errorChan)
- }
-}
-
-func SolverSingleUpstream(u *v1.Upstream, rwg RouteWorkerGroup, wg
*sync.WaitGroup, errorChan chan CRDStatus) {
- var (
- op string
- errNotify error
- )
- defer func() {
- if errNotify != nil {
- errorChan <- CRDStatus{Id: "", Status: "failure", Err:
errNotify}
- }
- wg.Done()
- }()
- var cluster string
- if u.Group != "" {
- cluster = u.Group
- }
- if currentUpstream, err :=
conf.Client.Cluster(cluster).Upstream().Get(context.TODO(), u.FullName); err !=
nil && err != cache.ErrNotFound {
- log.Errorf("failed to find upstream %s: %s", u.FullName, err)
- errNotify = err
- return
- } else {
- if paddingUpstream(u, currentUpstream) {
- op = Create
- } else {
- op = Update
- }
-
- if op == Create {
- if u.FromKind == WatchFromKind {
- // We don't have a pre-defined upstream and the
current upstream updating from
- // endpoints.
- return
- }
- if _, err :=
conf.Client.Cluster(cluster).Upstream().Create(context.TODO(), u); err != nil {
- log.Errorf("failed to create upstream %s: %s",
u.FullName, err)
- return
- }
- } else {
- // diff
- hasDiff, err := utils.HasDiff(u, currentUpstream)
- if err != nil {
- errNotify = err
- return
- }
- if hasDiff {
- op = Update
- // 0.field check
- needToUpdate := true
- if currentUpstream.FromKind == ApisixUpstream {
// update from ApisixUpstream
- if u.FromKind != ApisixUpstream {
- // currentUpstream > u
- // set lb && health check
- needToUpdate = false
- }
- }
- if needToUpdate || u.FromKind == WatchFromKind {
- if u.FromKind == WatchFromKind {
- currentUpstream.Nodes = u.Nodes
- } else { // due to CRD update
- currentUpstream = u
- }
- if _, err =
conf.Client.Cluster(cluster).Upstream().Update(context.TODO(),
currentUpstream); err != nil {
- log.Errorf("failed to update
upstream %s: %s", u.FullName, err)
- return
- }
- }
- }
- }
- }
- log.Infof("solver upstream %s:%s", op, u.Name)
- // anyway, broadcast to route
- for _, sw := range rwg[u.Name] {
- sw.Event <- Event{}
- }
-}
diff --git a/pkg/seven/state/builder_test.go b/pkg/seven/state/builder_test.go
deleted file mode 100644
index a895fcf..0000000
--- a/pkg/seven/state/builder_test.go
+++ /dev/null
@@ -1,51 +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 (
- "testing"
-
- "github.com/apache/apisix-ingress-controller/pkg/seven/utils"
-)
-
-type school struct {
- *province
- Name string `json:"name"`
- Address string `json:"address"`
-}
-
-type province struct {
- Location string `json:"location"`
-}
-
-func Test_diff(t *testing.T) {
- //p1 := &province{Location: "jiangsu"}
- p2 := &province{Location: "zh"}
- s1 := &school{Name: "hello", Address: "this is a address"}
- s2 := &school{Name: "hello", Address: "this is a address", province: p2}
- t.Log(s1)
- t.Log(s2)
- if d, err := utils.Diff(s1, s2); err != nil {
- t.Log(err.Error())
- } else {
- //t.Logf("s1 vs s2 hasDiff ? %v", d)
- t.Log(d)
- for _, delta := range d.Deltas() {
- t.Log(delta.Similarity())
- }
-
- }
-
-}
diff --git a/pkg/seven/state/event.go b/pkg/seven/state/event.go
index 3a750f9..8c354e0 100644
--- a/pkg/seven/state/event.go
+++ b/pkg/seven/state/event.go
@@ -14,36 +14,8 @@
// limitations under the License.
package state
-import (
- v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-type ApisixCombination struct {
- Routes []*v1.Route
- Services []*v1.Service
- Upstreams []*v1.Upstream
-}
-
-type RouteCompare struct {
- OldRoutes []*v1.Route
- NewRoutes []*v1.Route
-}
-
-type Quit struct {
- Err error
-}
-
const (
- RouteKind = "route"
- ServiceKind = "service"
- UpstreamKind = "upstream"
- Create = "create"
- Update = "update"
- Delete = "delete"
+ Create = "create"
+ Update = "update"
+ Delete = "delete"
)
-
-type Event struct {
- Kind string // route/service/upstream
- Op string // create update delete
- Obj interface{} // the obj of kind
-}
diff --git a/pkg/seven/state/route_worker.go b/pkg/seven/state/route_worker.go
deleted file mode 100644
index ed28234..0000000
--- a/pkg/seven/state/route_worker.go
+++ /dev/null
@@ -1,68 +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"
- "sync"
-
- v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-)
-
-type routeWorker struct {
- *v1.Route
- Event chan Event
- Ctx context.Context
- Wg *sync.WaitGroup
- ErrorChan chan CRDStatus
-}
-
-// RouteWorkerGroup for broadcast from service to route
-type RouteWorkerGroup map[string][]*routeWorker
-
-// start start watch event
-func (w *routeWorker) start() {
- w.Event = make(chan Event)
- go func() {
- for {
- select {
- case <-w.Event:
- w.trigger()
- case <-w.Ctx.Done():
- return
- }
- }
- }()
-}
-
-func (rg *RouteWorkerGroup) Add(key string, rw *routeWorker) {
- routes := (*rg)[key]
- if routes == nil {
- routes = make([]*routeWorker, 0)
- }
- routes = append(routes, rw)
- (*rg)[key] = routes
-}
-
-func (rg *RouteWorkerGroup) Delete(key string, route *routeWorker) {
- routes := (*rg)[key]
- result := make([]*routeWorker, 0)
- for _, r := range routes {
- if r.Name != route.Name {
- result = append(result, r)
- }
- }
- (*rg)[key] = result
-}
diff --git a/pkg/seven/state/solver.go b/pkg/seven/state/solver.go
index 7d49746..d17cdeb 100644
--- a/pkg/seven/state/solver.go
+++ b/pkg/seven/state/solver.go
@@ -16,201 +16,17 @@ package state
import (
"context"
- "errors"
- "sync"
- "time"
- "go.uber.org/multierr"
-
- "github.com/apache/apisix-ingress-controller/pkg/apisix/cache"
- "github.com/apache/apisix-ingress-controller/pkg/log"
"github.com/apache/apisix-ingress-controller/pkg/seven/conf"
v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
)
-var UpstreamQueue chan UpstreamQueueObj
-
-func init() {
- UpstreamQueue = make(chan UpstreamQueueObj, 500)
- go WatchUpstream()
-}
-
-func WatchUpstream() {
- for {
- uqo := <-UpstreamQueue
- SolverUpstream(uqo.Upstreams, uqo.RouteWorkerGroup, uqo.Wg,
uqo.ErrorChan)
- }
-}
-
-// Solver
-func (s *ApisixCombination) Solver() (string, error) {
- // define the result notify
- timeout := 10 * time.Second
- resultChan := make(chan CRDStatus)
- ctx := context.Background()
- ctx, _ = context.WithTimeout(ctx, timeout)
- go s.SyncWithGroup(ctx, "", resultChan)
-
- return WaitWorkerGroup("", resultChan)
-}
-
-func (s *ApisixCombination) Remove() error {
- // services
- for _, svc := range s.Services {
- var cluster string
- if svc.Group != "" {
- cluster = svc.Group
- }
- svcInCache, err :=
conf.Client.Cluster(cluster).Service().Get(context.TODO(), svc.FullName)
- if err != nil {
- if err == cache.ErrNotFound {
- log.Errorf("failed to remove service %s: %s",
svc.FullName, err)
- continue
- } else {
- return err
- }
- }
- _ = paddingService(svc, svcInCache)
- err =
conf.Client.Cluster(cluster).Service().Delete(context.TODO(), svc)
- if err != nil {
- if err == cache.ErrNotFound {
- log.Errorf("failed to remove service %s: %s",
svc.FullName, err)
- } else if err == cache.ErrStillInUse {
- log.Warnf("failed to remove service %s: %s",
svc.FullName, err)
- } else {
- return err
- }
- }
- }
-
- // upstreams
- for _, ups := range s.Upstreams {
- var cluster string
- if ups.Group != "" {
- cluster = ups.Group
- }
- upsInCache, err :=
conf.Client.Cluster(cluster).Upstream().Get(context.TODO(), ups.FullName)
- if err != nil {
- if err == cache.ErrNotFound {
- log.Errorf("failed to remove service %s: %s",
ups.FullName, err)
- continue
- } else {
- return err
- }
- }
- _ = paddingUpstream(ups, upsInCache)
- err =
conf.Client.Cluster(cluster).Upstream().Delete(context.TODO(), ups)
- if err == cache.ErrNotFound {
- log.Errorf("failed to remove upstream %s: %s",
ups.FullName, err)
- } else if err == cache.ErrStillInUse {
- log.Warnf("failed to remove upstream %s: %s",
ups.FullName, err)
- } else {
- return err
- }
- }
- return nil
-}
-
-func waitTimeout(ctx context.Context, wg *sync.WaitGroup, resultChan chan
CRDStatus) {
- c := make(chan struct{})
- go func() {
- defer close(c)
- wg.Wait()
- }()
- select {
- case <-c:
- resultChan <- CRDStatus{Id: "", Status: "success", Err: nil}
- case <-ctx.Done():
- resultChan <- CRDStatus{Id: "", Status: "failure", Err:
errors.New("timeout")}
- }
-}
-
-func (s *ApisixCombination) SyncWithGroup(ctx context.Context, id string,
resultChan chan CRDStatus) {
- var wg sync.WaitGroup
- count := len(s.Routes) + len(s.Services) + len(s.Upstreams)
- wg.Add(count)
- // goroutine for sync route/service/upstream
- // route
- rwg := NewRouteWorkers(ctx, s.Routes, &wg, resultChan)
- // upstream
- uqo := &UpstreamQueueObj{Upstreams: s.Upstreams, RouteWorkerGroup: rwg,
Wg: &wg, ErrorChan: resultChan}
- uqo.AddQueue()
-
- waitTimeout(ctx, &wg, resultChan)
-}
-
-func WaitWorkerGroup(id string, resultChan chan CRDStatus) (string, error) {
- r := <-resultChan
- return id, r.Err
-}
-
-// UpstreamQueueObj for upstream queue
-type UpstreamQueueObj struct {
- Upstreams []*v1.Upstream
- RouteWorkerGroup RouteWorkerGroup
- Wg *sync.WaitGroup
- ErrorChan chan CRDStatus
-}
-
type CRDStatus struct {
Id string `json:"id"`
Status string `json:"status"`
Err error `json:"err"`
}
-type ResourceStatus struct {
- Kind string `json:"kind"`
- Id string `json:"id"`
- Err error `json:"err"`
-}
-
-// AddQueue make upstreams in order
-// upstreams is group by CRD
-func (uqo *UpstreamQueueObj) AddQueue() {
- UpstreamQueue <- *uqo
-}
-
-type ServiceQueueObj struct {
- Services []*v1.Service
- RouteWorkerGroup RouteWorkerGroup
-}
-
-// Sync remove from apisix
-func (rc *RouteCompare) Sync() error {
- var merr error
- for _, old := range rc.OldRoutes {
- needToDel := true
- for _, nr := range rc.NewRoutes {
- if old.Name == nr.Name {
- needToDel = false
- break
- }
- }
- if needToDel {
- var cluster string
- if old.Group != "" {
- cluster = old.Group
- }
-
- // old should inject the ID.
- route, err :=
conf.Client.Cluster(cluster).Route().Get(context.TODO(), old.FullName)
- if err != nil {
- if err != cache.ErrNotFound {
- merr = multierr.Append(merr, err)
- }
- continue
- }
-
- _ = paddingRoute(old, route)
- if err :=
conf.Client.Cluster(cluster).Route().Delete(context.TODO(), old); err != nil {
- log.Errorf("failed to delete route %s from
APISIX: %s", old.Name, err)
- merr = multierr.Append(merr, err)
- }
- }
- }
- return merr
-}
-
func SyncSsl(ssl *v1.Ssl, method string) error {
var cluster string
if ssl.Group != "" {
diff --git a/test/e2e/ingress/resourcepushing.go
b/test/e2e/ingress/resourcepushing.go
index 7e590e7..0e2db4e 100644
--- a/test/e2e/ingress/resourcepushing.go
+++ b/test/e2e/ingress/resourcepushing.go
@@ -26,7 +26,6 @@ import (
)
var _ = ginkgo.Describe("ApisixRoute Testing", func() {
-
opts := &scaffold.Options{
Name: "default",
Kubeconfig: scaffold.GetKubeconfig(),
@@ -73,7 +72,7 @@ spec:
s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK).Body().Raw()
})
- ginkgo.It("create and then remove", func() {
+ ginkgo.It("create, update, then remove", func() {
backendSvc, backendSvcPort := s.DefaultHTTPBackend()
apisixRoute := fmt.Sprintf(`
apiVersion: apisix.apache.org/v2alpha1
@@ -99,14 +98,182 @@ spec:
err = s.EnsureNumApisixUpstreamsCreated(1)
assert.Nil(ginkgo.GinkgoT(), err, "Checking number of
upstreams")
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK)
+
+ // update
+ apisixRoute = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /ip
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Foo
+ op: Equal
+ value: "barbaz"
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(apisixRoute))
+ // TODO When ingress controller can feedback the lifecycle of
CRDs to the
+ // status field, we can poll it rather than sleeping.
+ time.Sleep(10 * time.Second)
+
+ err = s.EnsureNumApisixRoutesCreated(1)
+ assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+ err = s.EnsureNumApisixUpstreamsCreated(1)
+ assert.Nil(ginkgo.GinkgoT(), err, "Checking number of
upstreams")
+
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusNotFound)
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").WithHeader("X-Foo", "barbaz").Expect().Status(http.StatusOK)
+
// remove
assert.Nil(ginkgo.GinkgoT(),
s.RemoveResourceByString(apisixRoute))
-
// TODO When ingress controller can feedback the lifecycle of
CRDs to the
// status field, we can poll it rather than sleeping.
time.Sleep(10 * time.Second)
ups, err := s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err, "list upstreams error")
assert.Len(ginkgo.GinkgoT(), ups, 0, "upstreams nodes not
expect")
+
+ body := s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusNotFound).Body().Raw()
+ assert.Contains(ginkgo.GinkgoT(), body, "404 Route Not Found")
+ })
+
+ ginkgo.It("change route rule name", func() {
+ backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+ apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /ip
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(apisixRoute), "creating ApisixRoute")
+ assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1))
+ assert.Nil(ginkgo.GinkgoT(),
s.EnsureNumApisixUpstreamsCreated(1))
+
+ routes, err := s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err, "listing routes in APISIX")
+ assert.Len(ginkgo.GinkgoT(), routes, 1)
+
+ upstreams, err := s.ListApisixUpstreams()
+ assert.Nil(ginkgo.GinkgoT(), err, "listing upstreams in APISIX")
+ assert.Len(ginkgo.GinkgoT(), upstreams, 1)
+
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().Status(http.StatusOK)
+
+ apisixRoute = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1_1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /headers
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0])
+
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(apisixRoute), "creating ApisixRoute")
+ assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(1))
+ assert.Nil(ginkgo.GinkgoT(),
s.EnsureNumApisixUpstreamsCreated(1))
+
+ newRoutes, err := s.ListApisixRoutes()
+ assert.Nil(ginkgo.GinkgoT(), err, "listing routes in APISIX")
+ assert.Len(ginkgo.GinkgoT(), newRoutes, 1)
+ newUpstreams, err := s.ListApisixUpstreams()
+ assert.Nil(ginkgo.GinkgoT(), err, "listing upstreams in APISIX")
+ assert.Len(ginkgo.GinkgoT(), newUpstreams, 1)
+
+ // Upstream doesn't change.
+ assert.Equal(ginkgo.GinkgoT(), newUpstreams[0].ID,
upstreams[0].ID)
+ assert.Equal(ginkgo.GinkgoT(), newUpstreams[0].FullName,
upstreams[0].FullName)
+
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().
+ Status(http.StatusNotFound).
+ Body().Contains("404 Route Not Found")
+
+ s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.com").Expect().
+ Status(http.StatusOK)
+ })
+
+ ginkgo.It("same route rule name between two ApisixRoute objects",
func() {
+ backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+ apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /ip
+ backend:
+ serviceName: %s
+ servicePort: %d
+---
+apiVersion: apisix.apache.org/v2alpha1
+kind: ApisixRoute
+metadata:
+ name: httpbin-route-2
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.com
+ paths:
+ - /headers
+ backend:
+ serviceName: %s
+ servicePort: %d
+`, backendSvc, backendSvcPort[0], backendSvc, backendSvcPort[0])
+
+ assert.Nil(ginkgo.GinkgoT(),
s.CreateResourceFromString(apisixRoute), "creating ApisixRoute")
+ assert.Nil(ginkgo.GinkgoT(), s.EnsureNumApisixRoutesCreated(2))
+ assert.Nil(ginkgo.GinkgoT(),
s.EnsureNumApisixUpstreamsCreated(1))
+
+ s.NewAPISIXClient().GET("/ip").WithHeader("Host",
"httpbin.com").Expect().
+ Status(http.StatusOK).
+ Body().
+ Contains("origin")
+ s.NewAPISIXClient().GET("/headers").WithHeader("Host",
"httpbin.com").Expect().
+ Status(http.StatusOK).
+ Body().
+ Contains("headers").
+ Contains("httpbin.com")
})
})