mirror of
https://github.com/alibaba/higress.git
synced 2026-05-11 06:17:26 +08:00
feat: support KnativeIngress (#524)
This commit is contained in:
61
go.mod
61
go.mod
@@ -21,16 +21,13 @@ require (
|
||||
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5
|
||||
github.com/dubbogo/gost v1.13.1
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1
|
||||
github.com/evanphx/json-patch/v5 v5.6.0
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/yamlfmt v0.10.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/consul/api v1.23.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hudl/fargo v1.4.0
|
||||
github.com/kylelemons/godebug v1.1.0
|
||||
github.com/nacos-group/nacos-sdk-go v1.0.8
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.1.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
@@ -41,23 +38,22 @@ require (
|
||||
google.golang.org/grpc v1.48.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
helm.sh/helm/v3 v3.7.1
|
||||
istio.io/api v0.0.0-20211122181927-8da52c66ff23
|
||||
istio.io/client-go v1.12.0-rc.1.0.20211118171212-b744b6f111e4
|
||||
istio.io/gogo-genproto v0.0.0-20211115195057-0e34bdd2be67
|
||||
istio.io/istio v0.0.0
|
||||
istio.io/pkg v0.0.0-20211115195056-e379f31ee62a
|
||||
k8s.io/api v0.22.2
|
||||
k8s.io/apimachinery v0.22.2
|
||||
k8s.io/api v0.22.5
|
||||
k8s.io/apimachinery v0.22.5
|
||||
k8s.io/cli-runtime v0.22.2
|
||||
k8s.io/client-go v0.22.2
|
||||
k8s.io/client-go v0.22.5
|
||||
k8s.io/kubectl v0.22.2
|
||||
sigs.k8s.io/controller-runtime v0.10.2
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.97.0 // indirect
|
||||
cloud.google.com/go v0.98.0 // indirect
|
||||
cloud.google.com/go/logging v1.4.2 // indirect
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
@@ -91,6 +87,7 @@ require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20220520190051-1e77728a1eaa // indirect
|
||||
github.com/containerd/containerd v1.5.7 // indirect
|
||||
github.com/containerd/continuity v0.1.0 // indirect
|
||||
@@ -116,16 +113,15 @@ require (
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-kit/log v0.1.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||
github.com/go-logr/logr v0.4.0 // indirect
|
||||
github.com/go-logr/logr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.4.8 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-containerregistry v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
@@ -153,9 +149,7 @@ require (
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.13.0 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.7 // indirect
|
||||
@@ -168,7 +162,7 @@ require (
|
||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
|
||||
github.com/lib/pq v1.10.0 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.12 // indirect
|
||||
@@ -200,7 +194,6 @@ require (
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.21.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.6.1 // indirect
|
||||
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc // indirect
|
||||
github.com/russross/blackfriday v1.5.2 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
@@ -230,9 +223,9 @@ require (
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v3 v3.0.1 // indirect
|
||||
gomodules.xyz/orderedmap v0.1.0 // indirect
|
||||
google.golang.org/api v0.59.0 // indirect
|
||||
google.golang.org/api v0.61.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a // indirect
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 // indirect
|
||||
gopkg.in/gcfg.v1 v1.2.3 // indirect
|
||||
gopkg.in/gorp.v1 v1.7.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
@@ -241,11 +234,10 @@ require (
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.22.2 // indirect
|
||||
k8s.io/apiserver v0.22.2 // indirect
|
||||
k8s.io/component-base v0.22.2 // indirect
|
||||
k8s.io/klog/v2 v2.10.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20211020163157-7327e2aaee2b // indirect
|
||||
k8s.io/klog/v2 v2.40.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
oras.land/oras-go v0.4.0 // indirect
|
||||
sigs.k8s.io/gateway-api v0.4.0 // indirect
|
||||
@@ -266,3 +258,30 @@ replace istio.io/pkg => ./external/pkg
|
||||
replace istio.io/client-go => ./external/client-go
|
||||
|
||||
replace istio.io/istio => ./external/istio
|
||||
|
||||
replace (
|
||||
github.com/go-logr/logr => github.com/go-logr/logr v0.4.0
|
||||
k8s.io/api => k8s.io/api v0.22.2
|
||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.2
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.22.2
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.2
|
||||
k8s.io/client-go => k8s.io/client-go v0.22.2
|
||||
k8s.io/component-base => k8s.io/component-base v0.22.2
|
||||
k8s.io/klog/v2 => k8s.io/klog/v2 v2.10.0
|
||||
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20211020163157-7327e2aaee2b // indirect
|
||||
k8s.io/kubectl => k8s.io/kubectl v0.22.2
|
||||
k8s.io/utils => k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
sigs.k8s.io/gateway-api => sigs.k8s.io/gateway-api v0.4.0 // indirect
|
||||
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.8.11 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.11.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/evanphx/json-patch/v5 v5.6.0
|
||||
github.com/google/yamlfmt v0.10.0
|
||||
github.com/kylelemons/godebug v1.1.0
|
||||
helm.sh/helm/v3 v3.7.1
|
||||
k8s.io/apiextensions-apiserver v0.25.4
|
||||
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165
|
||||
knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77
|
||||
)
|
||||
|
||||
285
go.sum
285
go.sum
@@ -27,8 +27,9 @@ cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWc
|
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.98.0 h1:w6LozQJyDDEyhf64Uusu1LCcnLt0I1VMLiJC2kV+eXk=
|
||||
cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
|
||||
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=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@@ -49,8 +50,11 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0=
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj3gsxcuytSqtH0dxSWW1RE=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
@@ -60,43 +64,29 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210929163055-e81b3f25be97/go.mod h1:WpB7kf89yJUETZxQnP1kgYPNwlT2jjdDYUCoxVggM3g=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
@@ -145,11 +135,8 @@ github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:m
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/RageCage64/multilinediff v0.2.0 h1:yNSpSF5NXIrmo6bRIgO4Q0g7SXqFD4j/WEcBE+BdCFY=
|
||||
@@ -157,15 +144,17 @@ github.com/RageCage64/multilinediff v0.2.0/go.mod h1:pKr+KLgP0gvRzA+yv0/IUaYQuBY
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/agiledragon/gomonkey/v2 v2.9.0 h1:PDiKKybR596O6FHW+RVSG0Z7uGCBNbmbUXh3uCNQ7Hc=
|
||||
github.com/agiledragon/gomonkey/v2 v2.9.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8=
|
||||
github.com/alecthomas/jsonschema v0.0.0-20180308105923-f2c93856175a/go.mod h1:qpebaTNSsyUn5rPSJMsfqEtDw71TTggXM6stUDI16HA=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -177,7 +166,6 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
@@ -190,7 +178,6 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
@@ -215,11 +202,13 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k=
|
||||
github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
|
||||
@@ -236,6 +225,7 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
|
||||
@@ -394,7 +384,6 @@ github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@@ -423,6 +412,9 @@ github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27N
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E=
|
||||
github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E=
|
||||
github.com/dgryski/go-lttb v0.0.0-20180810165845-318fcdf10a77/go.mod h1:Va5MyIzkU0rAM92tn3hb3Anb7oz7KcnixF49+2wOMe4=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20210926092439-1563384b69df h1:zafDqOsnugdrReF9Pe0wybnfFtEIaegSyHNIvnwKPVk=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20210926092439-1563384b69df/go.mod h1:ZDZib/BOniVWcXcsy0voU8gR00znhe5VJm47d3H2Y5g=
|
||||
@@ -441,12 +433,10 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6Uezg
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 h1:XoR8SSVziXe698dt4uZYDfsmHpKLemqAgFyndQsq5Kw=
|
||||
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
|
||||
@@ -454,6 +444,7 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210914135545-4980593459a1/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
@@ -464,7 +455,6 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
@@ -491,6 +481,7 @@ github.com/florianl/go-nflog/v2 v2.0.1/go.mod h1:g+SOgM/SuePn9bvS/eo3Ild7J71nSb2
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2 h1:cZqz+yOJ/R64LcKjNQOdARott/jP7BnUQ9Ah7KaZCvw=
|
||||
@@ -508,12 +499,9 @@ github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui72
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
@@ -529,64 +517,26 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
|
||||
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
||||
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
@@ -596,6 +546,7 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
|
||||
github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
|
||||
github.com/gobuffalo/flect v0.2.4/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8=
|
||||
github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=
|
||||
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
|
||||
github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
|
||||
@@ -650,7 +601,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -670,11 +620,20 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
|
||||
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
|
||||
github.com/gonum/diff v0.0.0-20181124234638-500114f11e71/go.mod h1:22dM4PLscQl+Nzf64qNBurVJvfyvZELT0iRW2l/NN70=
|
||||
github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
|
||||
github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y=
|
||||
github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
|
||||
github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A=
|
||||
github.com/gonum/mathext v0.0.0-20181121095525-8a4bf007ea55/go.mod h1:fmo8aiSEWkJeiGXUJf+sPvuDgEFgqIoZSs843ePKrGg=
|
||||
github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
|
||||
github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs=
|
||||
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/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
@@ -696,11 +655,13 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/go-containerregistry v0.6.0 h1:niQ+8XD//kKgArIFwDVBXsWVWbde16LPdHMyNwSC8h4=
|
||||
github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v27 v27.0.6/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3/go.mod h1:YzLcVlL+NqWnmUEPuhS1LxDDwGO9WNbVlEXaF4IH35g=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@@ -737,14 +698,11 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
@@ -756,8 +714,9 @@ github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
|
||||
@@ -808,6 +767,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
|
||||
@@ -841,9 +801,16 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/influxdata/tdigest v0.0.0-20180711151920-a7d76c6f093a/go.mod h1:9GkyshztGufsdPQWjH+ifgnIr3xNUL5syI70g2dzU1o=
|
||||
github.com/istio/viper v1.3.3-0.20190515210538-2789fed3109c/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
|
||||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
@@ -894,6 +861,7 @@ github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q
|
||||
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
|
||||
github.com/karrick/godirwalk v1.15.8 h1:7+rWAZPn9zuRxaIqqT8Ohs2Q2Ac0msBqwRdxNCr2VVs=
|
||||
github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -901,8 +869,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs=
|
||||
github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@@ -962,14 +931,13 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
|
||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
||||
github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
|
||||
@@ -1032,6 +1000,7 @@ github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqA
|
||||
github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.17/go.mod h1:WgzbA6oji13JREwiNsRDNfl7jYdPnmz+VEuLrA+/48M=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
|
||||
@@ -1072,8 +1041,6 @@ github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J
|
||||
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 h1:yH0SvLzcbZxcJXho2yh7CqdENGMQe73Cw3woZBpPli0=
|
||||
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -1129,8 +1096,9 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@@ -1184,6 +1152,7 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.3.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
@@ -1199,6 +1168,7 @@ github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoU
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -1266,7 +1236,9 @@ github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9
|
||||
github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||
github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8=
|
||||
github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ=
|
||||
github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@@ -1276,6 +1248,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc h1:BD7uZqkN8CpjJtN/tScAKiccBikU4dlqe/gNrkRaPY4=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
@@ -1359,7 +1332,6 @@ github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSW
|
||||
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
@@ -1370,6 +1342,7 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU=
|
||||
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -1397,20 +1370,21 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto=
|
||||
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk=
|
||||
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE=
|
||||
github.com/tsenart/go-tsz v0.0.0-20180814232043-cdeb9e1e981e/go.mod h1:SWZznP1z5Ki7hDT2ioqiFKEse8K9tU2OUvaRI0NeGQo=
|
||||
github.com/tsenart/vegeta/v12 v12.8.4/go.mod h1:ZiJtwLn/9M4fTPdMY7bdbIeyNeFVE8/AHbWFqCsUuho=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
@@ -1423,6 +1397,9 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@@ -1442,6 +1419,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
|
||||
@@ -1468,9 +1446,6 @@ go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Ox
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0-alpha.0/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@@ -1505,6 +1480,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
@@ -1534,34 +1510,34 @@ golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/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/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1600,16 +1576,14 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1622,7 +1596,6 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -1666,7 +1639,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
@@ -1676,8 +1648,12 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -1716,7 +1692,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1727,12 +1702,10 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1815,7 +1788,6 @@ golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1842,8 +1814,12 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1852,9 +1828,9 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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=
|
||||
@@ -1863,6 +1839,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1873,16 +1850,15 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
@@ -1893,7 +1869,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -1951,6 +1926,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
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=
|
||||
@@ -1981,6 +1957,7 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
@@ -1999,8 +1976,9 @@ google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv
|
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=
|
||||
google.golang.org/api v0.59.0 h1:fPfFO7gttlXYo2ALuD3HxJzh8vaF++4youI0BkFL6GE=
|
||||
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
|
||||
google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -2046,6 +2024,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
@@ -2083,9 +2062,12 @@ google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEc
|
||||
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a h1:8maMHMQp9NroHXhc3HelFX9Ay2lWlXLcdH5mw5Biz0s=
|
||||
google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 h1:DN5b3HU13J4sMd/QjDx34U6afpaexKTDdop+26pdjdk=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
@@ -2121,6 +2103,7 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
|
||||
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
@@ -2210,132 +2193,65 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
istio.io/gogo-genproto v0.0.0-20210113155706-4daf5697332f/go.mod h1:6BwTZRNbWS570wHX/uR1Wqk5e0157TofTAUMzT7N4+s=
|
||||
istio.io/gogo-genproto v0.0.0-20211115195057-0e34bdd2be67 h1:vkYEm5mvjuGBxhXSAkFUxVMbcItNu8Wf/jWpJ27b0hQ=
|
||||
istio.io/gogo-genproto v0.0.0-20211115195057-0e34bdd2be67/go.mod h1:6BwTZRNbWS570wHX/uR1Wqk5e0157TofTAUMzT7N4+s=
|
||||
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
|
||||
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
|
||||
k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
|
||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU=
|
||||
k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
|
||||
k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
|
||||
k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
|
||||
k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
|
||||
k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
|
||||
k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
|
||||
k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE=
|
||||
k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
|
||||
k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4=
|
||||
k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
|
||||
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
|
||||
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
|
||||
k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=
|
||||
k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
|
||||
k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
|
||||
k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||
k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU=
|
||||
k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
|
||||
k8s.io/apiserver v0.22.2 h1:TdIfZJc6YNhu2WxeAOWq1TvukHF0Sfx0+ln4XK9qnL4=
|
||||
k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
|
||||
k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo=
|
||||
k8s.io/cli-runtime v0.22.2 h1:fsd9rFk9FSaVq4SUq1fM27c8CFGsYZUJ/3BkgmjYWuY=
|
||||
k8s.io/cli-runtime v0.22.2/go.mod h1:tkm2YeORFpbgQHEK/igqttvPTRIHFRz5kATlw53zlMI=
|
||||
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
|
||||
k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
|
||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||
k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA=
|
||||
k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU=
|
||||
k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
|
||||
k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc=
|
||||
k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U=
|
||||
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
|
||||
k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo=
|
||||
k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
|
||||
k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
|
||||
k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
|
||||
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
|
||||
k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||
k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ=
|
||||
k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
|
||||
k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk=
|
||||
k8s.io/component-base v0.22.2 h1:vNIvE0AIrLhjX8drH0BgCNJcR4QZxMXcJzBsDplDx9M=
|
||||
k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug=
|
||||
k8s.io/component-helpers v0.22.1/go.mod h1:QvBcDbX+qU5I2tMZABBF5fRwAlQwiv771IGBHK9WYh4=
|
||||
k8s.io/component-helpers v0.22.2/go.mod h1:+N61JAR9aKYSWbnLA88YcFr9K/6ISYvRNybX7QW7Rs8=
|
||||
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
||||
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE=
|
||||
k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/kube-openapi v0.0.0-20211020163157-7327e2aaee2b h1:RQzI0hL8LPCNd9eAZvuG8orAUrxXFiVqBKSU8fs6ygc=
|
||||
k8s.io/kube-openapi v0.0.0-20211020163157-7327e2aaee2b/go.mod h1:gULf0pSS32YtLlO7+li/EV8/0y5mG/sO32H4OUsHIQg=
|
||||
k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw=
|
||||
k8s.io/kubectl v0.22.2 h1:KMyYNZoBshaL3XKx04X07DtpoD4vMrdkfiN/G2Qx/PU=
|
||||
k8s.io/kubectl v0.22.2/go.mod h1:BApg2j0edxLArCOfO0ievI27EeTQqBDMNU9VQH734iQ=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E=
|
||||
k8s.io/metrics v0.22.2/go.mod h1:GUcsBtpsqQD1tKFS/2wCKu4ZBowwRncLOJH1rgWs3uw=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
knative.dev/hack v0.0.0-20220224013837-e1785985d364/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165 h1:mkUDPTqfRPNhsUTVOH53IOx0Utzlfwl48t8lLc1bfL4=
|
||||
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165/go.mod h1:EdQTSLl8BDeLLrC8pymGOiPMRAknFg+7oRO6MMUts94=
|
||||
knative.dev/pkg v0.0.0-20220228195509-fe264173447b/go.mod h1:SsH9J6Gz+CvrHmoL0TELJXmMmohqKSQ5bpJvCv+1+ZI=
|
||||
knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77 h1:eIH936a0/1X/XQOMN9+O3fw9spGvOJiMVKsBuu8J47U=
|
||||
knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77/go.mod h1:SsH9J6Gz+CvrHmoL0TELJXmMmohqKSQ5bpJvCv+1+ZI=
|
||||
oras.land/oras-go v0.4.0 h1:u6+7D+raZDYHwlz/uOwNANiRmyYDSSMW7A9E1xXycUQ=
|
||||
oras.land/oras-go v0.4.0/go.mod h1:VJcU+VE4rkclUbum5C0O7deEZbBYnsnpbGSACwTjOcg=
|
||||
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
|
||||
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/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
|
||||
sigs.k8s.io/controller-runtime v0.9.6/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
|
||||
@@ -2354,11 +2270,8 @@ sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gH
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
|
||||
sigs.k8s.io/mcs-api v0.1.0 h1:edDbg0oRGfXw8TmZjKYep06LcJLv/qcYLidejnUp0PM=
|
||||
sigs.k8s.io/mcs-api v0.1.0/go.mod h1:gGiAryeFNB4GBsq2LBmVqSgKoobLxt+p7ii/WG5QYYw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||
|
||||
@@ -117,3 +117,10 @@ rules:
|
||||
- apiGroups: ["config.istio.io", "security.istio.io", "networking.istio.io", "authentication.istio.io", "rbac.istio.io", "telemetry.istio.io", "extensions.istio.io"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
resources: ["*"]
|
||||
# knative KIngress configuration
|
||||
- apiGroups: ["networking.internal.knative.dev"]
|
||||
verbs: ["get","list","watch"]
|
||||
resources: ["ingresses"]
|
||||
- apiGroups: ["networking.internal.knative.dev"]
|
||||
resources: ["ingresses/status"]
|
||||
verbs: ["get","patch","update"]
|
||||
@@ -20,6 +20,10 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/mcp"
|
||||
"github.com/alibaba/higress/pkg/ingress/translation"
|
||||
higresskube "github.com/alibaba/higress/pkg/kube"
|
||||
prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
@@ -46,11 +50,6 @@ import (
|
||||
"istio.io/pkg/log"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
ingressconfig "github.com/alibaba/higress/pkg/ingress/config"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/mcp"
|
||||
higresskube "github.com/alibaba/higress/pkg/kube"
|
||||
)
|
||||
|
||||
type XdsOptions struct {
|
||||
@@ -225,9 +224,12 @@ func (s *Server) initConfigController() error {
|
||||
if options.ClusterId == "Kubernetes" {
|
||||
options.ClusterId = ""
|
||||
}
|
||||
ingressConfig := ingressconfig.NewIngressConfig(s.kubeClient, s.xdsServer, ns, options.ClusterId)
|
||||
ingressController := ingressConfig.AddLocalCluster(options)
|
||||
|
||||
ingressConfig := translation.NewIngressTranslation(s.kubeClient, s.xdsServer, ns, options.ClusterId)
|
||||
ingressController, kingressController := ingressConfig.AddLocalCluster(options)
|
||||
|
||||
s.configStores = append(s.configStores, ingressConfig)
|
||||
|
||||
// Wrap the config controller with a cache.
|
||||
aggregateConfigController, err := configaggregate.MakeCache(s.configStores)
|
||||
if err != nil {
|
||||
@@ -242,7 +244,7 @@ func (s *Server) initConfigController() error {
|
||||
|
||||
// Defer starting the controller until after the service is created.
|
||||
s.server.RunComponent(func(stop <-chan struct{}) error {
|
||||
if err := ingressConfig.InitializeCluster(ingressController, stop); err != nil {
|
||||
if err := ingressConfig.InitializeCluster(ingressController, kingressController, stop); err != nil {
|
||||
return err
|
||||
}
|
||||
go s.configController.Run(stop)
|
||||
|
||||
@@ -15,3 +15,7 @@
|
||||
package constants
|
||||
|
||||
const DefaultIngressClass = "higress"
|
||||
|
||||
const KnativeIngressCRDName = "ingresses.networking.internal.knative.dev"
|
||||
|
||||
const KnativeServicesCRDName = "services.serving.knative.dev"
|
||||
|
||||
552
pkg/ingress/config/kingress_config.go
Normal file
552
pkg/ingress/config/kingress_config.go
Normal file
@@ -0,0 +1,552 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 config
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/util/sets"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
listersv1 "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/kingress"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/secret"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
"github.com/alibaba/higress/registry/reconcile"
|
||||
)
|
||||
|
||||
var (
|
||||
_ model.ConfigStoreCache = &KIngressConfig{}
|
||||
_ model.IngressStore = &KIngressConfig{}
|
||||
)
|
||||
|
||||
type KIngressConfig struct {
|
||||
// key: cluster id
|
||||
remoteIngressControllers map[string]common.KIngressController
|
||||
mutex sync.RWMutex
|
||||
|
||||
ingressRouteCache model.IngressRouteCollection
|
||||
ingressDomainCache model.IngressDomainCollection
|
||||
|
||||
localKubeClient kube.Client
|
||||
virtualServiceHandlers []model.EventHandler
|
||||
gatewayHandlers []model.EventHandler
|
||||
envoyFilterHandlers []model.EventHandler
|
||||
WatchErrorHandler cache.WatchErrorHandler
|
||||
|
||||
cachedEnvoyFilters []config.Config
|
||||
|
||||
watchedSecretSet sets.Set
|
||||
|
||||
RegistryReconciler *reconcile.Reconciler
|
||||
|
||||
XDSUpdater model.XDSUpdater
|
||||
|
||||
annotationHandler annotations.AnnotationHandler
|
||||
|
||||
globalGatewayName string
|
||||
|
||||
namespace string
|
||||
|
||||
clusterId string
|
||||
}
|
||||
|
||||
func NewKIngressConfig(localKubeClient kube.Client, XDSUpdater model.XDSUpdater, namespace, clusterId string) *KIngressConfig {
|
||||
if localKubeClient.KIngressInformer() == nil {
|
||||
return nil
|
||||
}
|
||||
if clusterId == "Kubernetes" {
|
||||
clusterId = ""
|
||||
}
|
||||
config := &KIngressConfig{
|
||||
remoteIngressControllers: make(map[string]common.KIngressController),
|
||||
localKubeClient: localKubeClient,
|
||||
XDSUpdater: XDSUpdater,
|
||||
annotationHandler: annotations.NewAnnotationHandlerManager(),
|
||||
clusterId: clusterId,
|
||||
globalGatewayName: namespace + "/" +
|
||||
common.CreateConvertedName(clusterId, "global"),
|
||||
watchedSecretSet: sets.NewSet(),
|
||||
namespace: namespace,
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) RegisterEventHandler(kind config.GroupVersionKind, f model.EventHandler) {
|
||||
IngressLog.Infof("register resource %v", kind)
|
||||
switch kind {
|
||||
case gvk.VirtualService:
|
||||
m.virtualServiceHandlers = append(m.virtualServiceHandlers, f)
|
||||
|
||||
case gvk.Gateway:
|
||||
m.gatewayHandlers = append(m.gatewayHandlers, f)
|
||||
|
||||
case gvk.EnvoyFilter:
|
||||
m.envoyFilterHandlers = append(m.envoyFilterHandlers, f)
|
||||
}
|
||||
|
||||
for _, remoteIngressController := range m.remoteIngressControllers {
|
||||
remoteIngressController.RegisterEventHandler(kind, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) AddLocalCluster(options common.Options) common.KIngressController {
|
||||
secretController := secret.NewController(m.localKubeClient, options.ClusterId)
|
||||
secretController.AddEventHandler(m.ReflectSecretChanges)
|
||||
|
||||
var ingressController common.KIngressController
|
||||
|
||||
ingressController = kingress.NewController(m.localKubeClient, m.localKubeClient, options, secretController)
|
||||
|
||||
m.remoteIngressControllers[options.ClusterId] = ingressController
|
||||
return ingressController
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) InitializeCluster(ingressController common.KIngressController, stop <-chan struct{}) error {
|
||||
_ = ingressController.SetWatchErrorHandler(m.WatchErrorHandler)
|
||||
go ingressController.Run(stop)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) List(typ config.GroupVersionKind, namespace string) ([]config.Config, error) {
|
||||
if typ == gvk.EnvoyFilter || typ == gvk.DestinationRule || typ == gvk.WasmPlugin || typ == gvk.ServiceEntry {
|
||||
return nil, nil
|
||||
}
|
||||
if typ != gvk.Gateway && typ != gvk.VirtualService {
|
||||
return nil, common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
// Currently, only support list all namespaces gateways or virtualservices.
|
||||
if namespace != "" {
|
||||
IngressLog.Warnf("ingress store only support type %s of all namespace.", typ)
|
||||
return nil, common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
var configs []config.Config
|
||||
m.mutex.RLock()
|
||||
for _, ingressController := range m.remoteIngressControllers {
|
||||
configs = append(configs, ingressController.List()...)
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
|
||||
common.SortIngressByCreationTime(configs)
|
||||
wrapperConfigs := m.createWrapperConfigs(configs)
|
||||
|
||||
IngressLog.Infof("resource type %s, configs number %d", typ, len(wrapperConfigs))
|
||||
switch typ {
|
||||
case gvk.Gateway:
|
||||
return m.convertGateways(wrapperConfigs), nil
|
||||
case gvk.VirtualService:
|
||||
return m.convertVirtualService(wrapperConfigs), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) createWrapperConfigs(configs []config.Config) []common.WrapperConfig {
|
||||
var wrapperConfigs []common.WrapperConfig
|
||||
|
||||
// Init global context
|
||||
clusterSecretListers := map[string]listersv1.SecretLister{}
|
||||
clusterServiceListers := map[string]listersv1.ServiceLister{}
|
||||
m.mutex.RLock()
|
||||
for clusterId, controller := range m.remoteIngressControllers {
|
||||
clusterSecretListers[clusterId] = controller.SecretLister()
|
||||
clusterServiceListers[clusterId] = controller.ServiceLister()
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
globalContext := &annotations.GlobalContext{
|
||||
WatchedSecrets: sets.NewSet(),
|
||||
ClusterSecretLister: clusterSecretListers,
|
||||
ClusterServiceList: clusterServiceListers,
|
||||
}
|
||||
|
||||
for idx := range configs {
|
||||
rawConfig := configs[idx]
|
||||
annotationsConfig := &annotations.Ingress{
|
||||
Meta: annotations.Meta{
|
||||
Namespace: rawConfig.Namespace,
|
||||
Name: rawConfig.Name,
|
||||
RawClusterId: common.GetRawClusterId(rawConfig.Annotations),
|
||||
ClusterId: common.GetClusterId(rawConfig.Annotations),
|
||||
},
|
||||
}
|
||||
_ = m.annotationHandler.Parse(rawConfig.Annotations, annotationsConfig, globalContext)
|
||||
wrapperConfigs = append(wrapperConfigs, common.WrapperConfig{
|
||||
Config: &rawConfig,
|
||||
AnnotationsConfig: annotationsConfig,
|
||||
})
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
m.watchedSecretSet = globalContext.WatchedSecrets
|
||||
m.mutex.Unlock()
|
||||
|
||||
return wrapperConfigs
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) convertGateways(configs []common.WrapperConfig) []config.Config {
|
||||
convertOptions := common.ConvertOptions{
|
||||
IngressDomainCache: common.NewIngressDomainCache(),
|
||||
Gateways: map[string]*common.WrapperGateway{},
|
||||
}
|
||||
|
||||
for idx := range configs {
|
||||
cfg := configs[idx]
|
||||
clusterId := common.GetClusterId(cfg.Config.Annotations)
|
||||
m.mutex.RLock()
|
||||
ingressController := m.remoteIngressControllers[clusterId]
|
||||
m.mutex.RUnlock()
|
||||
if ingressController == nil {
|
||||
continue
|
||||
}
|
||||
if err := ingressController.ConvertGateway(&convertOptions, &cfg); err != nil {
|
||||
IngressLog.Errorf("Convert ingress %s/%s to gateway fail in cluster %s, err %v", cfg.Config.Namespace, cfg.Config.Name, clusterId, err)
|
||||
}
|
||||
}
|
||||
|
||||
// apply annotation
|
||||
for _, wrapperGateway := range convertOptions.Gateways {
|
||||
m.annotationHandler.ApplyGateway(wrapperGateway.Gateway, wrapperGateway.WrapperConfig.AnnotationsConfig)
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
m.ingressDomainCache = convertOptions.IngressDomainCache.Extract()
|
||||
m.mutex.Unlock()
|
||||
out := make([]config.Config, 0, len(convertOptions.Gateways))
|
||||
for _, gateway := range convertOptions.Gateways {
|
||||
cleanHost := common.CleanHost(gateway.Host)
|
||||
out = append(out, config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: common.CreateConvertedName(constants.IstioIngressGatewayName, cleanHost),
|
||||
Namespace: m.namespace,
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: gateway.ClusterId,
|
||||
common.HostAnnotation: gateway.Host,
|
||||
},
|
||||
},
|
||||
Spec: gateway.Gateway,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) convertVirtualService(configs []common.WrapperConfig) []config.Config {
|
||||
convertOptions := common.ConvertOptions{
|
||||
IngressRouteCache: common.NewIngressRouteCache(),
|
||||
VirtualServices: map[string]*common.WrapperVirtualService{},
|
||||
HTTPRoutes: map[string][]*common.WrapperHTTPRoute{},
|
||||
Route2Ingress: map[string]*common.WrapperConfigWithRuleKey{},
|
||||
}
|
||||
|
||||
// convert http route
|
||||
for idx := range configs {
|
||||
cfg := configs[idx]
|
||||
clusterId := common.GetClusterId(cfg.Config.Annotations)
|
||||
m.mutex.RLock()
|
||||
ingressController := m.remoteIngressControllers[clusterId]
|
||||
m.mutex.RUnlock()
|
||||
if ingressController == nil {
|
||||
continue
|
||||
}
|
||||
if err := ingressController.ConvertHTTPRoute(&convertOptions, &cfg); err != nil {
|
||||
IngressLog.Errorf("Convert ingress %s/%s to HTTP route fail in cluster %s, err %v", cfg.Config.Namespace, cfg.Config.Name, clusterId, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply annotation on routes
|
||||
for _, routes := range convertOptions.HTTPRoutes {
|
||||
for _, route := range routes {
|
||||
m.annotationHandler.ApplyRoute(route.HTTPRoute, route.WrapperConfig.AnnotationsConfig)
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize weighted cluster to make sure the sum of weight is 100.
|
||||
for _, host := range convertOptions.HTTPRoutes {
|
||||
for _, route := range host {
|
||||
normalizeWeightedKCluster(convertOptions.IngressRouteCache, route)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply annotation on virtual services Only IP-control and do nothing
|
||||
for _, virtualService := range convertOptions.VirtualServices {
|
||||
m.annotationHandler.ApplyVirtualServiceHandler(virtualService.VirtualService, virtualService.WrapperConfig.AnnotationsConfig)
|
||||
}
|
||||
|
||||
// Apply app root for per host.
|
||||
m.applyAppRoot(&convertOptions)
|
||||
|
||||
// Apply internal active redirect for error page.
|
||||
m.applyInternalActiveRedirect(&convertOptions)
|
||||
|
||||
m.mutex.Lock()
|
||||
m.ingressRouteCache = convertOptions.IngressRouteCache.Extract()
|
||||
m.mutex.Unlock()
|
||||
|
||||
// Convert http route to virtual service
|
||||
out := make([]config.Config, 0, len(convertOptions.HTTPRoutes))
|
||||
for host, routes := range convertOptions.HTTPRoutes {
|
||||
if len(routes) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cleanHost := common.CleanHost(host)
|
||||
// namespace/name, name format: (istio cluster id)-host
|
||||
gateways := []string{m.namespace + "/" +
|
||||
common.CreateConvertedName(m.clusterId, cleanHost),
|
||||
common.CreateConvertedName(constants.IstioIngressGatewayName, cleanHost)}
|
||||
if host != "*" {
|
||||
gateways = append(gateways, m.globalGatewayName)
|
||||
}
|
||||
|
||||
wrapperVS, exist := convertOptions.VirtualServices[host]
|
||||
if !exist {
|
||||
IngressLog.Warnf("virtual service for host %s does not exist.", host)
|
||||
}
|
||||
vs := wrapperVS.VirtualService
|
||||
vs.Gateways = gateways
|
||||
|
||||
for _, route := range routes {
|
||||
vs.Http = append(vs.Http, route.HTTPRoute)
|
||||
}
|
||||
|
||||
firstRoute := routes[0]
|
||||
out = append(out, config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
Name: common.CreateConvertedName(constants.IstioIngressGatewayName, firstRoute.WrapperConfig.Config.Namespace, firstRoute.WrapperConfig.Config.Name, cleanHost),
|
||||
Namespace: m.namespace,
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: firstRoute.ClusterId,
|
||||
},
|
||||
},
|
||||
Spec: vs,
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Make sure that the sum of traffic split ratio is 100, if it is not 100, it will be normalized
|
||||
func normalizeWeightedKCluster(cache *common.IngressRouteCache, route *common.WrapperHTTPRoute) {
|
||||
if len(route.HTTPRoute.Route) == 1 {
|
||||
route.HTTPRoute.Route[0].Weight = 100
|
||||
return
|
||||
}
|
||||
|
||||
var weightTotal int32 = 0
|
||||
for _, routeDestination := range route.HTTPRoute.Route {
|
||||
weightTotal += routeDestination.Weight
|
||||
}
|
||||
var sum int32
|
||||
for idx, routeDestination := range route.HTTPRoute.Route {
|
||||
if idx == 0 {
|
||||
continue
|
||||
}
|
||||
weight := float32(routeDestination.Weight) / float32(weightTotal)
|
||||
routeDestination.Weight = int32(weight * 100)
|
||||
sum += routeDestination.Weight
|
||||
}
|
||||
route.HTTPRoute.Route[0].Weight = 100 - sum
|
||||
// Update the recorded status in ingress builder
|
||||
if cache != nil {
|
||||
cache.Update(route)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) applyAppRoot(convertOptions *common.ConvertOptions) {
|
||||
for host, wrapVS := range convertOptions.VirtualServices {
|
||||
if wrapVS.AppRoot != "" {
|
||||
route := &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{
|
||||
Name: common.CreateConvertedName(host, "app-root"),
|
||||
Match: []*networking.HTTPMatchRequest{
|
||||
{
|
||||
Uri: &networking.StringMatch{
|
||||
MatchType: &networking.StringMatch_Exact{
|
||||
Exact: "/",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Redirect: &networking.HTTPRedirect{
|
||||
RedirectCode: 302,
|
||||
Uri: wrapVS.AppRoot,
|
||||
},
|
||||
},
|
||||
WrapperConfig: wrapVS.WrapperConfig,
|
||||
ClusterId: wrapVS.WrapperConfig.AnnotationsConfig.ClusterId,
|
||||
}
|
||||
convertOptions.HTTPRoutes[host] = append([]*common.WrapperHTTPRoute{route}, convertOptions.HTTPRoutes[host]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) applyInternalActiveRedirect(convertOptions *common.ConvertOptions) {
|
||||
for host, routes := range convertOptions.HTTPRoutes {
|
||||
var tempRoutes []*common.WrapperHTTPRoute
|
||||
for _, route := range routes {
|
||||
tempRoutes = append(tempRoutes, route)
|
||||
if route.HTTPRoute.InternalActiveRedirect != nil {
|
||||
fallbackConfig := route.WrapperConfig.AnnotationsConfig.Fallback
|
||||
if fallbackConfig == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
typedNamespace := fallbackConfig.DefaultBackend
|
||||
internalRedirectRoute := route.HTTPRoute.DeepCopy()
|
||||
internalRedirectRoute.Name = internalRedirectRoute.Name + annotations.FallbackRouteNameSuffix
|
||||
internalRedirectRoute.InternalActiveRedirect = nil
|
||||
internalRedirectRoute.Match = []*networking.HTTPMatchRequest{
|
||||
{
|
||||
Uri: &networking.StringMatch{
|
||||
MatchType: &networking.StringMatch_Exact{
|
||||
Exact: "/",
|
||||
},
|
||||
},
|
||||
Headers: map[string]*networking.StringMatch{
|
||||
annotations.FallbackInjectHeaderRouteName: {
|
||||
MatchType: &networking.StringMatch_Exact{
|
||||
Exact: internalRedirectRoute.Name,
|
||||
},
|
||||
},
|
||||
annotations.FallbackInjectFallbackService: {
|
||||
MatchType: &networking.StringMatch_Exact{
|
||||
Exact: typedNamespace.String(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
internalRedirectRoute.Route = []*networking.HTTPRouteDestination{
|
||||
{
|
||||
Destination: &networking.Destination{
|
||||
Host: util.CreateServiceFQDN(typedNamespace.Namespace, typedNamespace.Name),
|
||||
Port: &networking.PortSelector{
|
||||
Number: fallbackConfig.Port,
|
||||
},
|
||||
},
|
||||
Weight: 100,
|
||||
},
|
||||
}
|
||||
|
||||
tempRoutes = append([]*common.WrapperHTTPRoute{{
|
||||
HTTPRoute: internalRedirectRoute,
|
||||
WrapperConfig: route.WrapperConfig,
|
||||
ClusterId: route.ClusterId,
|
||||
}}, tempRoutes...)
|
||||
}
|
||||
}
|
||||
convertOptions.HTTPRoutes[host] = tempRoutes
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) ReflectSecretChanges(clusterNamespacedName util.ClusterNamespacedName) {
|
||||
var hit bool
|
||||
m.mutex.RLock()
|
||||
if m.watchedSecretSet.Contains(clusterNamespacedName.String()) {
|
||||
hit = true
|
||||
}
|
||||
m.mutex.RUnlock()
|
||||
|
||||
if hit {
|
||||
push := func(kind config.GroupVersionKind) {
|
||||
m.XDSUpdater.ConfigUpdate(&model.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[model.ConfigKey]struct{}{{
|
||||
Kind: kind,
|
||||
Name: clusterNamespacedName.Name,
|
||||
Namespace: clusterNamespacedName.Namespace,
|
||||
}: {}},
|
||||
Reason: []model.TriggerReason{"auth-secret-change"},
|
||||
})
|
||||
}
|
||||
push(gvk.VirtualService)
|
||||
push(gvk.EnvoyFilter)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Run(stop <-chan struct{}) {}
|
||||
|
||||
func (m *KIngressConfig) HasSynced() bool {
|
||||
IngressLog.Info("In Kingress Synced.")
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
|
||||
for _, remoteIngressController := range m.remoteIngressControllers {
|
||||
IngressLog.Info("In Kingress Synced.", remoteIngressController)
|
||||
if !remoteIngressController.HasSynced() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
IngressLog.Info("Ingress config controller synced.")
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) SetWatchErrorHandler(f func(r *cache.Reflector, err error)) error {
|
||||
m.WatchErrorHandler = f
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) GetIngressRoutes() model.IngressRouteCollection {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
return m.ingressRouteCache
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) GetIngressDomains() model.IngressDomainCollection {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
return m.ingressDomainCache
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Schemas() collection.Schemas {
|
||||
return common.IngressIR
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Get(config.GroupVersionKind, string, string) *config.Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Create(config.Config) (revision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Update(config.Config) (newRevision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) UpdateStatus(config.Config) (newRevision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Patch(config.Config, config.PatchFunc) (string, error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *KIngressConfig) Delete(config.GroupVersionKind, string, string, *string) error {
|
||||
return common.ErrUnsupportedOp
|
||||
}
|
||||
481
pkg/ingress/config/kingress_config_test.go
Normal file
481
pkg/ingress/config/kingress_config_test.go
Normal file
@@ -0,0 +1,481 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
ingress "knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
kcontrollerv1 "github.com/alibaba/higress/pkg/ingress/kube/kingress"
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
)
|
||||
|
||||
func TestNormalizeKWeightedCluster(t *testing.T) {
|
||||
validate := func(route *common.WrapperHTTPRoute) int32 {
|
||||
var total int32
|
||||
fmt.Print("----------------------------")
|
||||
for _, routeDestination := range route.HTTPRoute.Route {
|
||||
total += routeDestination.Weight
|
||||
fmt.Print(routeDestination.Weight)
|
||||
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
var testCases []*common.WrapperHTTPRoute
|
||||
testCases = append(testCases, &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{
|
||||
Route: []*networking.HTTPRouteDestination{
|
||||
{
|
||||
Weight: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
testCases = append(testCases, &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{
|
||||
Route: []*networking.HTTPRouteDestination{
|
||||
{
|
||||
Weight: 98,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testCases = append(testCases, &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{
|
||||
Route: []*networking.HTTPRouteDestination{
|
||||
{
|
||||
Weight: 0,
|
||||
},
|
||||
{
|
||||
Weight: 48,
|
||||
},
|
||||
{
|
||||
Weight: 48,
|
||||
},
|
||||
},
|
||||
},
|
||||
WeightTotal: 100,
|
||||
})
|
||||
|
||||
testCases = append(testCases, &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{
|
||||
Route: []*networking.HTTPRouteDestination{
|
||||
{
|
||||
Weight: 0,
|
||||
},
|
||||
{
|
||||
Weight: 48,
|
||||
},
|
||||
{
|
||||
Weight: 48,
|
||||
},
|
||||
},
|
||||
},
|
||||
WeightTotal: 80,
|
||||
})
|
||||
|
||||
for _, route := range testCases {
|
||||
t.Run("", func(t *testing.T) {
|
||||
normalizeWeightedKCluster(nil, route)
|
||||
if validate(route) != 100 {
|
||||
t.Fatalf("Weight sum should be 100, but actual is %d", validate(route))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertGatewaysForKIngress(t *testing.T) {
|
||||
fake := kube.NewFakeClient()
|
||||
v1Options := common.Options{
|
||||
Enable: true,
|
||||
ClusterId: "kingress",
|
||||
RawClusterId: "kingress__",
|
||||
}
|
||||
kingressV1Controller := kcontrollerv1.NewController(fake, fake, v1Options, nil)
|
||||
m := NewKIngressConfig(fake, nil, "wakanda", "gw-123-istio")
|
||||
m.remoteIngressControllers = map[string]common.KIngressController{
|
||||
"kingress": kingressV1Controller,
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
inputConfig []common.WrapperConfig
|
||||
expect map[string]config.Config
|
||||
}{
|
||||
{
|
||||
name: "kingress",
|
||||
inputConfig: []common.WrapperConfig{
|
||||
{
|
||||
Config: &config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "test-1",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
},
|
||||
},
|
||||
Spec: ingress.IngressSpec{
|
||||
HTTPOption: ingress.HTTPOptionEnabled,
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
SecretName: "test-com",
|
||||
},
|
||||
},
|
||||
Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{"foo.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
{
|
||||
Config: &config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "test-2",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
},
|
||||
},
|
||||
Spec: ingress.IngressSpec{
|
||||
HTTPOption: ingress.HTTPOptionRedirected,
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"foo.com"},
|
||||
SecretName: "foo-com",
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
SecretName: "test-com-2",
|
||||
},
|
||||
},
|
||||
Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{"foo.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
{
|
||||
Hosts: []string{"bar.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
{
|
||||
Config: &config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "test-3",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
},
|
||||
},
|
||||
Spec: ingress.IngressSpec{
|
||||
HTTPOption: ingress.HTTPOptionEnabled,
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"foo.com"},
|
||||
SecretName: "foo-com",
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
SecretName: "test-com-3",
|
||||
},
|
||||
},
|
||||
Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{"foo.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
{
|
||||
Hosts: []string{"bar.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test.com"},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{
|
||||
{
|
||||
Path: "/test",
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "wakanda",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expect: map[string]config.Config{
|
||||
"foo.com": {
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: "istio-autogenerated-k8s-ingress-foo-com",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
common.HostAnnotation: "foo.com",
|
||||
},
|
||||
},
|
||||
Spec: &networking.Gateway{
|
||||
Servers: []*networking.Server{
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
Name: "http-80-ingress-kingress-wakanda-test-1-foo-com",
|
||||
},
|
||||
Hosts: []string{"foo.com"},
|
||||
//Tls: &networking.ServerTLSSettings{
|
||||
// HttpsRedirect: true,
|
||||
//},
|
||||
},
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 443,
|
||||
Protocol: "HTTPS",
|
||||
Name: "https-443-ingress-kingress-wakanda-test-2-foo-com",
|
||||
},
|
||||
Hosts: []string{"foo.com"},
|
||||
Tls: &networking.ServerTLSSettings{
|
||||
Mode: networking.ServerTLSSettings_SIMPLE,
|
||||
CredentialName: "kubernetes-ingress://kingress__/wakanda/foo-com",
|
||||
//CipherSuites: []string{"ECDHE-RSA-AES128-GCM-SHA256", "AES256-SHA"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"test.com": {
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: "istio-autogenerated-k8s-ingress-test-com",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
common.HostAnnotation: "test.com",
|
||||
},
|
||||
},
|
||||
Spec: &networking.Gateway{
|
||||
Servers: []*networking.Server{
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
Name: "http-80-ingress-kingress-wakanda-test-1-test-com",
|
||||
},
|
||||
Hosts: []string{"test.com"},
|
||||
//Tls: &networking.ServerTLSSettings{
|
||||
// HttpsRedirect: true,
|
||||
//},
|
||||
},
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 443,
|
||||
Protocol: "HTTPS",
|
||||
Name: "https-443-ingress-kingress-wakanda-test-1-test-com",
|
||||
},
|
||||
Hosts: []string{"test.com"},
|
||||
Tls: &networking.ServerTLSSettings{
|
||||
Mode: networking.ServerTLSSettings_SIMPLE,
|
||||
CredentialName: "kubernetes-ingress://kingress__/wakanda/test-com",
|
||||
//CipherSuites: []string{"ECDHE-RSA-AES128-GCM-SHA256", "AES256-SHA"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"bar.com": {
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: "istio-autogenerated-k8s-ingress-bar-com",
|
||||
Namespace: "wakanda",
|
||||
Annotations: map[string]string{
|
||||
common.ClusterIdAnnotation: "kingress",
|
||||
common.HostAnnotation: "bar.com",
|
||||
},
|
||||
},
|
||||
Spec: &networking.Gateway{
|
||||
Servers: []*networking.Server{
|
||||
{
|
||||
Port: &networking.Port{
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
Name: "http-80-ingress-kingress-wakanda-test-2-bar-com",
|
||||
},
|
||||
Hosts: []string{"bar.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := m.convertGateways(testCase.inputConfig)
|
||||
|
||||
target := map[string]config.Config{}
|
||||
for _, item := range result {
|
||||
host := common.GetHost(item.Annotations)
|
||||
fmt.Print(item)
|
||||
target[host] = item
|
||||
}
|
||||
assert.Equal(t, testCase.expect, target)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -139,3 +139,27 @@ type IngressController interface {
|
||||
// HasSynced returns true after initial cache synchronization is complete
|
||||
HasSynced() bool
|
||||
}
|
||||
|
||||
type KIngressController interface {
|
||||
// RegisterEventHandler adds a handler to receive config update events for a
|
||||
// configuration type
|
||||
RegisterEventHandler(kind config.GroupVersionKind, handler model.EventHandler)
|
||||
|
||||
List() []config.Config
|
||||
|
||||
ServiceLister() listerv1.ServiceLister
|
||||
|
||||
SecretLister() listerv1.SecretLister
|
||||
|
||||
ConvertGateway(convertOptions *ConvertOptions, wrapper *WrapperConfig) error
|
||||
|
||||
ConvertHTTPRoute(convertOptions *ConvertOptions, wrapper *WrapperConfig) error
|
||||
|
||||
// Run until a signal is received
|
||||
Run(stop <-chan struct{})
|
||||
|
||||
SetWatchErrorHandler(func(r *cache.Reflector, err error)) error
|
||||
|
||||
// HasSynced returns true after initial cache synchronization is complete
|
||||
HasSynced() bool
|
||||
}
|
||||
|
||||
751
pkg/ingress/kube/kingress/controller.go
Normal file
751
pkg/ingress/kube/kingress/controller.go
Normal file
@@ -0,0 +1,751 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 kingress
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
"path"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/model/credentials"
|
||||
"istio.io/istio/pilot/pkg/util/sets"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/protocol"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
kset "k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
listerv1 "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
ingress "knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
networkingv1alpha1 "knative.dev/networking/pkg/client/listers/networking/v1alpha1"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/kingress/resources"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/secret"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
)
|
||||
|
||||
var (
|
||||
_ common.KIngressController = &controller{}
|
||||
)
|
||||
|
||||
const (
|
||||
// ClassAnnotationKey points to the annotation for the class of this resource.
|
||||
ClassAnnotationKey = "networking.knative.dev/ingress.class"
|
||||
IngressClassName = "higress"
|
||||
)
|
||||
|
||||
type controller struct {
|
||||
queue workqueue.RateLimitingInterface
|
||||
virtualServiceHandlers []model.EventHandler
|
||||
gatewayHandlers []model.EventHandler
|
||||
envoyFilterHandlers []model.EventHandler
|
||||
|
||||
options common.Options
|
||||
|
||||
mutex sync.RWMutex
|
||||
// key: namespace/name
|
||||
ingresses map[string]*ingress.Ingress
|
||||
|
||||
ingressInformer cache.SharedInformer
|
||||
ingressLister networkingv1alpha1.IngressLister
|
||||
serviceInformer cache.SharedInformer
|
||||
serviceLister listerv1.ServiceLister
|
||||
secretController secret.SecretController
|
||||
statusSyncer *statusSyncer
|
||||
}
|
||||
|
||||
// NewController creates a new Kubernetes controller
|
||||
func NewController(localKubeClient, client kube.Client, options common.Options,
|
||||
secretController secret.SecretController) common.KIngressController {
|
||||
q := workqueue.NewRateLimitingQueue(workqueue.DefaultItemBasedRateLimiter())
|
||||
|
||||
//var namespace string = "default"
|
||||
ingressInformer := client.KIngressInformer().Networking().V1alpha1().Ingresses()
|
||||
serviceInformer := client.KubeInformer().Core().V1().Services()
|
||||
|
||||
c := &controller{
|
||||
options: options,
|
||||
queue: q,
|
||||
ingresses: make(map[string]*ingress.Ingress),
|
||||
ingressInformer: ingressInformer.Informer(),
|
||||
ingressLister: ingressInformer.Lister(),
|
||||
serviceInformer: serviceInformer.Informer(),
|
||||
serviceLister: serviceInformer.Lister(),
|
||||
secretController: secretController,
|
||||
}
|
||||
|
||||
handler := controllers.LatestVersionHandlerFuncs(controllers.EnqueueForSelf(q))
|
||||
c.ingressInformer.AddEventHandler(handler)
|
||||
|
||||
if options.EnableStatus {
|
||||
c.statusSyncer = newStatusSyncer(localKubeClient, client, c, options.SystemNamespace)
|
||||
} else {
|
||||
IngressLog.Infof("Disable status update for cluster %s", options.ClusterId)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *controller) ServiceLister() listerv1.ServiceLister {
|
||||
return c.serviceLister
|
||||
}
|
||||
|
||||
func (c *controller) SecretLister() listerv1.SecretLister {
|
||||
return c.secretController.Lister()
|
||||
}
|
||||
|
||||
func (c *controller) Run(stop <-chan struct{}) {
|
||||
if c.statusSyncer != nil {
|
||||
go c.statusSyncer.run(stop)
|
||||
}
|
||||
go c.secretController.Run(stop)
|
||||
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.queue.ShutDown()
|
||||
|
||||
if !cache.WaitForCacheSync(stop, c.HasSynced) {
|
||||
IngressLog.Errorf("Failed to sync ingress controller cache for cluster %s", c.options.ClusterId)
|
||||
return
|
||||
}
|
||||
go wait.Until(c.worker, time.Second, stop)
|
||||
<-stop
|
||||
}
|
||||
|
||||
func (c *controller) worker() {
|
||||
for c.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) processNextWorkItem() bool {
|
||||
key, quit := c.queue.Get()
|
||||
if quit {
|
||||
return false
|
||||
}
|
||||
defer c.queue.Done(key)
|
||||
ingressNamespacedName := key.(types.NamespacedName)
|
||||
if err := c.onEvent(ingressNamespacedName); err != nil {
|
||||
IngressLog.Errorf("error processing ingress item (%v) (retrying): %v, cluster: %s", key, err, c.options.ClusterId)
|
||||
c.queue.AddRateLimited(key)
|
||||
} else {
|
||||
c.queue.Forget(key)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *controller) onEvent(namespacedName types.NamespacedName) error {
|
||||
event := model.EventUpdate
|
||||
ing, err := c.ingressLister.Ingresses(namespacedName.Namespace).Get(namespacedName.Name)
|
||||
ing.Status.InitializeConditions()
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
event = model.EventDelete
|
||||
c.mutex.Lock()
|
||||
ing = c.ingresses[namespacedName.String()]
|
||||
delete(c.ingresses, namespacedName.String())
|
||||
c.mutex.Unlock()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// ingress deleted, and it is not processed before
|
||||
if ing == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// we should check need process only when event is not delete,
|
||||
// if it is delete event, and previously processed, we need to process too.
|
||||
if event != model.EventDelete {
|
||||
shouldProcess, err := c.shouldProcessIngressUpdate(ing)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !shouldProcess {
|
||||
IngressLog.Infof("no need process, ingress %s", namespacedName)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
vsmetadata := config.Meta{
|
||||
Name: ing.Name + "-" + "virtualservice",
|
||||
Namespace: ing.Namespace,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
efmetadata := config.Meta{
|
||||
Name: ing.Name + "-" + "envoyfilter",
|
||||
Namespace: ing.Namespace,
|
||||
GroupVersionKind: gvk.EnvoyFilter,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
gatewaymetadata := config.Meta{
|
||||
Name: ing.Name + "-" + "gateway",
|
||||
Namespace: ing.Namespace,
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
|
||||
for _, f := range c.virtualServiceHandlers {
|
||||
f(config.Config{Meta: vsmetadata}, config.Config{Meta: vsmetadata}, event)
|
||||
}
|
||||
|
||||
for _, f := range c.envoyFilterHandlers {
|
||||
f(config.Config{Meta: efmetadata}, config.Config{Meta: efmetadata}, event)
|
||||
}
|
||||
|
||||
for _, f := range c.gatewayHandlers {
|
||||
f(config.Config{Meta: gatewaymetadata}, config.Config{Meta: gatewaymetadata}, event)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) RegisterEventHandler(kind config.GroupVersionKind, f model.EventHandler) {
|
||||
switch kind {
|
||||
case gvk.VirtualService:
|
||||
c.virtualServiceHandlers = append(c.virtualServiceHandlers, f)
|
||||
case gvk.Gateway:
|
||||
c.gatewayHandlers = append(c.gatewayHandlers, f)
|
||||
case gvk.EnvoyFilter:
|
||||
c.envoyFilterHandlers = append(c.envoyFilterHandlers, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) SetWatchErrorHandler(handler func(r *cache.Reflector, err error)) error {
|
||||
var errs error
|
||||
if err := c.serviceInformer.SetWatchErrorHandler(handler); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
if err := c.ingressInformer.SetWatchErrorHandler(handler); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
if err := c.secretController.Informer().SetWatchErrorHandler(handler); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func (c *controller) HasSynced() bool {
|
||||
return c.ingressInformer.HasSynced() && c.serviceInformer.HasSynced() && c.secretController.HasSynced()
|
||||
}
|
||||
|
||||
func (c *controller) List() []config.Config {
|
||||
c.mutex.RLock()
|
||||
out := make([]config.Config, 0, len(c.ingresses))
|
||||
c.mutex.RUnlock()
|
||||
|
||||
for _, raw := range c.ingressInformer.GetStore().List() {
|
||||
ing, ok := raw.(*ingress.Ingress)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if should, err := c.shouldProcessIngress(ing); !should || err != nil {
|
||||
continue
|
||||
}
|
||||
copiedConfig := ing.DeepCopy()
|
||||
|
||||
outConfig := config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: copiedConfig.Name,
|
||||
Namespace: copiedConfig.Namespace,
|
||||
Annotations: common.CreateOrUpdateAnnotations(copiedConfig.Annotations, c.options),
|
||||
Labels: copiedConfig.Labels,
|
||||
CreationTimestamp: copiedConfig.CreationTimestamp.Time,
|
||||
},
|
||||
Spec: copiedConfig.Spec,
|
||||
}
|
||||
|
||||
out = append(out, outConfig)
|
||||
}
|
||||
|
||||
common.RecordIngressNumber(c.options.ClusterId, len(out))
|
||||
return out
|
||||
}
|
||||
|
||||
func extractTLSSecretName(host string, tls []ingress.IngressTLS) string {
|
||||
if len(tls) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, t := range tls {
|
||||
match := false
|
||||
for _, h := range t.Hosts {
|
||||
if h == host {
|
||||
match = true
|
||||
}
|
||||
}
|
||||
|
||||
if match {
|
||||
return t.SecretName
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig) error {
|
||||
if convertOptions == nil {
|
||||
return fmt.Errorf("convertOptions is nil")
|
||||
}
|
||||
if wrapper == nil {
|
||||
return fmt.Errorf("wrapperConfig is nil")
|
||||
}
|
||||
|
||||
cfg := wrapper.Config
|
||||
kingressv1alpha1, ok := cfg.Spec.(ingress.IngressSpec)
|
||||
|
||||
if !ok {
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, common.Unknown)
|
||||
return fmt.Errorf("convert type is invalid in cluster %s", c.options.ClusterId)
|
||||
}
|
||||
if len(kingressv1alpha1.Rules) == 0 {
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, common.EmptyRule)
|
||||
return fmt.Errorf("invalid ingress rule %s:%s in cluster %s, `rules` must be specified", cfg.Namespace, cfg.Name, c.options.ClusterId)
|
||||
}
|
||||
|
||||
for _, rule := range kingressv1alpha1.Rules {
|
||||
for _, ruleHost := range rule.Hosts {
|
||||
cleanHost := common.CleanHost(ruleHost)
|
||||
// Need create builder for every rule.
|
||||
domainBuilder := &common.IngressDomainBuilder{
|
||||
ClusterId: c.options.ClusterId,
|
||||
Protocol: common.HTTP,
|
||||
Host: ruleHost,
|
||||
Ingress: cfg,
|
||||
Event: common.Normal,
|
||||
}
|
||||
// Extract the previous gateway and builder
|
||||
wrapperGateway, exist := convertOptions.Gateways[ruleHost]
|
||||
preDomainBuilder, _ := convertOptions.IngressDomainCache.Valid[ruleHost]
|
||||
if !exist {
|
||||
wrapperGateway = &common.WrapperGateway{
|
||||
Gateway: &networking.Gateway{},
|
||||
WrapperConfig: wrapper,
|
||||
ClusterId: c.options.ClusterId,
|
||||
Host: ruleHost,
|
||||
}
|
||||
if c.options.GatewaySelectorKey != "" {
|
||||
wrapperGateway.Gateway.Selector = map[string]string{c.options.GatewaySelectorKey: c.options.GatewaySelectorValue}
|
||||
}
|
||||
if rule.Visibility == ingress.IngressVisibilityClusterLocal {
|
||||
wrapperGateway.Gateway.Servers = append(wrapperGateway.Gateway.Servers, &networking.Server{
|
||||
Port: &networking.Port{
|
||||
Number: 8081,
|
||||
Protocol: string(protocol.HTTP),
|
||||
Name: common.CreateConvertedName("http-8081-ingress", c.options.ClusterId, cfg.Namespace, cfg.Name, cleanHost),
|
||||
},
|
||||
Hosts: []string{ruleHost},
|
||||
})
|
||||
|
||||
} else {
|
||||
wrapperGateway.Gateway.Servers = append(wrapperGateway.Gateway.Servers, &networking.Server{
|
||||
Port: &networking.Port{
|
||||
Number: 80,
|
||||
Protocol: string(protocol.HTTP),
|
||||
Name: common.CreateConvertedName("http-80-ingress", c.options.ClusterId, cfg.Namespace, cfg.Name, cleanHost),
|
||||
},
|
||||
Hosts: []string{ruleHost},
|
||||
})
|
||||
}
|
||||
|
||||
// Add new gateway, builder
|
||||
convertOptions.Gateways[ruleHost] = wrapperGateway
|
||||
convertOptions.IngressDomainCache.Valid[ruleHost] = domainBuilder
|
||||
} else {
|
||||
// Fallback to get downstream tls from current ingress.
|
||||
if wrapperGateway.WrapperConfig.AnnotationsConfig.DownstreamTLS == nil {
|
||||
wrapperGateway.WrapperConfig.AnnotationsConfig.DownstreamTLS = wrapper.AnnotationsConfig.DownstreamTLS
|
||||
}
|
||||
}
|
||||
//Redirect option
|
||||
if isIngressPublic(&kingressv1alpha1) && (kingressv1alpha1.HTTPOption == ingress.HTTPOptionRedirected) {
|
||||
for _, server := range wrapperGateway.Gateway.Servers {
|
||||
if protocol.Parse(server.Port.Protocol).IsHTTP() {
|
||||
server.Tls = &networking.ServerTLSSettings{
|
||||
HttpsRedirect: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if isIngressPublic(&kingressv1alpha1) && (kingressv1alpha1.HTTPOption == ingress.HTTPOptionEnabled) {
|
||||
for _, server := range wrapperGateway.Gateway.Servers {
|
||||
if protocol.Parse(server.Port.Protocol).IsHTTP() {
|
||||
server.Tls = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There are no tls settings, so just skip.
|
||||
if len(kingressv1alpha1.TLS) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get tls secret matching the rule host
|
||||
secretName := extractTLSSecretName(ruleHost, kingressv1alpha1.TLS)
|
||||
if secretName == "" {
|
||||
// There no matching secret, so just skip.
|
||||
continue
|
||||
}
|
||||
|
||||
domainBuilder.Protocol = common.HTTPS
|
||||
domainBuilder.SecretName = path.Join(c.options.ClusterId, cfg.Namespace, secretName)
|
||||
|
||||
// There is a matching secret and the gateway has already a tls secret.
|
||||
// We should report the duplicated tls secret event.
|
||||
if wrapperGateway.IsHTTPS() {
|
||||
domainBuilder.Event = common.DuplicatedTls
|
||||
domainBuilder.PreIngress = preDomainBuilder.Ingress
|
||||
convertOptions.IngressDomainCache.Invalid = append(convertOptions.IngressDomainCache.Invalid,
|
||||
domainBuilder.Build())
|
||||
continue
|
||||
}
|
||||
|
||||
// Append https server
|
||||
wrapperGateway.Gateway.Servers = append(wrapperGateway.Gateway.Servers, &networking.Server{
|
||||
Port: &networking.Port{
|
||||
Number: 443,
|
||||
Protocol: string(protocol.HTTPS),
|
||||
Name: common.CreateConvertedName("https-443-ingress", c.options.ClusterId, cfg.Namespace, cfg.Name, cleanHost),
|
||||
},
|
||||
Hosts: []string{ruleHost},
|
||||
Tls: &networking.ServerTLSSettings{
|
||||
Mode: networking.ServerTLSSettings_SIMPLE,
|
||||
CredentialName: credentials.ToKubernetesIngressResource(c.options.RawClusterId, cfg.Namespace, secretName),
|
||||
},
|
||||
})
|
||||
|
||||
// Update domain builder
|
||||
convertOptions.IngressDomainCache.Valid[ruleHost] = domainBuilder
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) ConvertHTTPRoute(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig) error {
|
||||
if convertOptions == nil {
|
||||
return fmt.Errorf("convertOptions is nil")
|
||||
}
|
||||
if wrapper == nil {
|
||||
return fmt.Errorf("wrapperConfig is nil")
|
||||
}
|
||||
|
||||
cfg := wrapper.Config
|
||||
KingressV1, ok := cfg.Spec.(ingress.IngressSpec)
|
||||
if !ok {
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, common.Unknown)
|
||||
return fmt.Errorf("convert type is invalid in cluster %s", c.options.ClusterId)
|
||||
}
|
||||
if len(KingressV1.Rules) == 0 {
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, common.EmptyRule)
|
||||
return fmt.Errorf("invalid ingress rule %s:%s in cluster %s, `rules` must be specified", cfg.Namespace, cfg.Name, c.options.ClusterId)
|
||||
}
|
||||
convertOptions.HasDefaultBackend = false
|
||||
// In one ingress, we will limit the rule conflict.
|
||||
// When the host, pathType, path of two rule are same, we think there is a conflict event.
|
||||
definedRules := sets.NewSet()
|
||||
|
||||
var (
|
||||
// But in across ingresses case, we will restrict this limit.
|
||||
// When the {host, path, headers, method, params} of two rule in different ingress are same, we think there is a conflict event.
|
||||
tempRuleKey []string
|
||||
)
|
||||
|
||||
for _, rule := range KingressV1.Rules {
|
||||
for _, rulehost := range rule.Hosts {
|
||||
if rule.HTTP == nil || len(rule.HTTP.Paths) == 0 {
|
||||
IngressLog.Warnf("invalid ingress rule %s:%s for host %q in cluster %s, no paths defined", cfg.Namespace, cfg.Name, rulehost, c.options.ClusterId)
|
||||
continue
|
||||
}
|
||||
wrapperVS, exist := convertOptions.VirtualServices[rulehost]
|
||||
if !exist {
|
||||
wrapperVS = &common.WrapperVirtualService{
|
||||
VirtualService: &networking.VirtualService{
|
||||
Hosts: []string{rulehost},
|
||||
},
|
||||
WrapperConfig: wrapper,
|
||||
}
|
||||
convertOptions.VirtualServices[rulehost] = wrapperVS
|
||||
}
|
||||
wrapperHttpRoutes := make([]*common.WrapperHTTPRoute, 0, len(rule.HTTP.Paths))
|
||||
for _, httpPath := range rule.HTTP.Paths {
|
||||
wrapperHttpRoute := &common.WrapperHTTPRoute{
|
||||
HTTPRoute: &networking.HTTPRoute{},
|
||||
WrapperConfig: wrapper,
|
||||
Host: rulehost,
|
||||
ClusterId: c.options.ClusterId,
|
||||
}
|
||||
|
||||
var pathType common.PathType
|
||||
originPath := httpPath.Path
|
||||
pathType = common.Prefix
|
||||
wrapperHttpRoute.OriginPath = originPath
|
||||
wrapperHttpRoute.OriginPathType = pathType
|
||||
wrapperHttpRoute.HTTPRoute = resources.MakeVirtualServiceRoute(transformHosts(rulehost), &httpPath)
|
||||
wrapperHttpRoute.HTTPRoute.Name = common.GenerateUniqueRouteName(c.options.SystemNamespace, wrapperHttpRoute)
|
||||
ingressRouteBuilder := convertOptions.IngressRouteCache.New(wrapperHttpRoute)
|
||||
hostAndPath := wrapperHttpRoute.PathFormat()
|
||||
key := createRuleKey(cfg.Annotations, hostAndPath)
|
||||
wrapperHttpRoute.RuleKey = key
|
||||
if WrapPreIngress, exist := convertOptions.Route2Ingress[key]; exist {
|
||||
ingressRouteBuilder.PreIngress = WrapPreIngress.Config
|
||||
ingressRouteBuilder.Event = common.DuplicatedRoute
|
||||
}
|
||||
tempRuleKey = append(tempRuleKey, key)
|
||||
|
||||
// Two duplicated rules in the same ingress.
|
||||
if ingressRouteBuilder.Event == common.Normal {
|
||||
pathFormat := wrapperHttpRoute.PathFormat()
|
||||
if definedRules.Contains(pathFormat) {
|
||||
ingressRouteBuilder.PreIngress = cfg
|
||||
ingressRouteBuilder.Event = common.DuplicatedRoute
|
||||
}
|
||||
definedRules.Insert(pathFormat)
|
||||
}
|
||||
|
||||
// backend service check
|
||||
var event common.Event
|
||||
destinationConfig := wrapper.AnnotationsConfig.Destination
|
||||
event = c.IngressRouteBuilderServicesCheck(&httpPath, cfg.Namespace, ingressRouteBuilder, destinationConfig)
|
||||
|
||||
if destinationConfig != nil {
|
||||
wrapperHttpRoute.WeightTotal = int32(destinationConfig.WeightSum)
|
||||
}
|
||||
|
||||
if ingressRouteBuilder.Event != common.Normal {
|
||||
event = ingressRouteBuilder.Event
|
||||
}
|
||||
|
||||
if event != common.Normal {
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, event)
|
||||
ingressRouteBuilder.Event = event
|
||||
} else {
|
||||
wrapperHttpRoutes = append(wrapperHttpRoutes, wrapperHttpRoute)
|
||||
}
|
||||
convertOptions.IngressRouteCache.Add(ingressRouteBuilder)
|
||||
}
|
||||
|
||||
for idx, item := range tempRuleKey {
|
||||
if val, exist := convertOptions.Route2Ingress[item]; !exist || strings.Compare(val.RuleKey, tempRuleKey[idx]) != 0 {
|
||||
convertOptions.Route2Ingress[item] = &common.WrapperConfigWithRuleKey{
|
||||
Config: cfg,
|
||||
RuleKey: tempRuleKey[idx],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
old, f := convertOptions.HTTPRoutes[rulehost]
|
||||
if f {
|
||||
old = append(old, wrapperHttpRoutes...)
|
||||
convertOptions.HTTPRoutes[rulehost] = old
|
||||
} else {
|
||||
convertOptions.HTTPRoutes[rulehost] = wrapperHttpRoutes
|
||||
}
|
||||
|
||||
// Sort, exact -> prefix -> regex
|
||||
routes := convertOptions.HTTPRoutes[rulehost]
|
||||
IngressLog.Debugf("routes of host %s is %v", rulehost, routes)
|
||||
common.SortHTTPRoutes(routes)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (c *controller) IngressRouteBuilderServicesCheck(httppath *ingress.HTTPIngressPath, namespace string,
|
||||
builder *common.IngressRouteBuilder, config *annotations.DestinationConfig) common.Event {
|
||||
|
||||
//backend check
|
||||
if httppath.Splits == nil {
|
||||
return common.InvalidBackendService
|
||||
}
|
||||
for _, split := range httppath.Splits {
|
||||
if split.ServiceName == "" {
|
||||
return common.InvalidBackendService
|
||||
}
|
||||
backendService := model.BackendService{
|
||||
Namespace: namespace,
|
||||
Name: split.ServiceName,
|
||||
Port: uint32(split.ServicePort.IntValue()),
|
||||
Weight: int32(split.Percent),
|
||||
}
|
||||
builder.ServiceList = append(builder.ServiceList, backendService)
|
||||
}
|
||||
return common.Normal
|
||||
}
|
||||
|
||||
func (c *controller) shouldProcessIngressWithClass(ing *ingress.Ingress) bool {
|
||||
if classValue, found := ing.GetAnnotations()[ClassAnnotationKey]; !found || classValue != IngressClassName {
|
||||
IngressLog.Debugf("Ingress class %s does not match knative IngressCLassName %s.", classValue, IngressClassName)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *controller) shouldProcessIngress(i *ingress.Ingress) (bool, error) {
|
||||
//check namespace
|
||||
if c.shouldProcessIngressWithClass(i) {
|
||||
switch c.options.WatchNamespace {
|
||||
case "":
|
||||
return true, nil
|
||||
default:
|
||||
return c.options.WatchNamespace == i.Namespace, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
// shouldProcessIngressUpdate checks whether we should renotify registered handlers about an update event
|
||||
func (c *controller) shouldProcessIngressUpdate(ing *ingress.Ingress) (bool, error) {
|
||||
shouldProcess, err := c.shouldProcessIngress(ing)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
namespacedName := ing.Namespace + "/" + ing.Name
|
||||
if shouldProcess {
|
||||
// record processed ingress
|
||||
c.mutex.Lock()
|
||||
preConfig, exist := c.ingresses[namespacedName]
|
||||
c.ingresses[namespacedName] = ing
|
||||
c.mutex.Unlock()
|
||||
|
||||
// We only care about annotations, labels and spec.
|
||||
if exist {
|
||||
if !reflect.DeepEqual(preConfig.Annotations, ing.Annotations) {
|
||||
IngressLog.Debugf("Annotations of ingress %s changed, should process.", namespacedName)
|
||||
return true, nil
|
||||
}
|
||||
if !reflect.DeepEqual(preConfig.Labels, ing.Labels) {
|
||||
IngressLog.Debugf("Labels of ingress %s changed, should process.", namespacedName)
|
||||
return true, nil
|
||||
}
|
||||
if !reflect.DeepEqual(preConfig.Spec, ing.Spec) {
|
||||
IngressLog.Debugf("Spec of ingress %s changed, should process.", namespacedName)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
IngressLog.Debugf("First receive relative ingress %s, should process.", namespacedName)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
c.mutex.Lock()
|
||||
_, preProcessed := c.ingresses[namespacedName]
|
||||
// previous processed but should not currently, delete it
|
||||
if preProcessed && !shouldProcess {
|
||||
delete(c.ingresses, namespacedName)
|
||||
}
|
||||
c.mutex.Unlock()
|
||||
|
||||
return preProcessed, nil
|
||||
}
|
||||
|
||||
// createRuleKey according to the pathType, path, methods, headers, params of rules
|
||||
func createRuleKey(annots map[string]string, hostAndPath string) string {
|
||||
var (
|
||||
headers [][2]string
|
||||
params [][2]string
|
||||
sb strings.Builder
|
||||
)
|
||||
|
||||
sep := "\n\n"
|
||||
|
||||
// path
|
||||
sb.WriteString(hostAndPath)
|
||||
sb.WriteString(sep)
|
||||
|
||||
// methods
|
||||
if str, ok := annots[annotations.HigressAnnotationsPrefix+"/"+annotations.MatchMethod]; ok {
|
||||
sb.WriteString(str)
|
||||
}
|
||||
sb.WriteString(sep)
|
||||
|
||||
start := len(annotations.HigressAnnotationsPrefix) + 1 // example: higress.io/exact-match-header-key: value
|
||||
// headers && params
|
||||
for k, val := range annots {
|
||||
if idx := strings.Index(k, annotations.MatchHeader); idx != -1 {
|
||||
key := k[start:idx] + k[idx+len(annotations.MatchHeader)+1:]
|
||||
headers = append(headers, [2]string{key, val})
|
||||
}
|
||||
if idx := strings.Index(k, annotations.MatchQuery); idx != -1 {
|
||||
key := k[start:idx] + k[idx+len(annotations.MatchQuery)+1:]
|
||||
params = append(params, [2]string{key, val})
|
||||
}
|
||||
}
|
||||
sort.SliceStable(headers, func(i, j int) bool {
|
||||
return headers[i][0] < headers[j][0]
|
||||
})
|
||||
sort.SliceStable(params, func(i, j int) bool {
|
||||
return params[i][0] < params[j][0]
|
||||
})
|
||||
for idx := range headers {
|
||||
if idx != 0 {
|
||||
sb.WriteByte('\n')
|
||||
}
|
||||
sb.WriteString(headers[idx][0])
|
||||
sb.WriteByte('\t')
|
||||
sb.WriteString(headers[idx][1])
|
||||
}
|
||||
sb.WriteString(sep)
|
||||
for idx := range params {
|
||||
if idx != 0 {
|
||||
sb.WriteByte('\n')
|
||||
}
|
||||
sb.WriteString(params[idx][0])
|
||||
sb.WriteByte('\t')
|
||||
sb.WriteString(params[idx][1])
|
||||
}
|
||||
sb.WriteString(sep)
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func transformHosts(host string) kset.String {
|
||||
hosts := []string{host}
|
||||
out := kset.NewString()
|
||||
out.Insert(hosts...)
|
||||
return out
|
||||
}
|
||||
|
||||
func isIngressPublic(ingSpec *ingress.IngressSpec) bool {
|
||||
for _, rule := range ingSpec.Rules {
|
||||
if rule.Visibility == ingress.IngressVisibilityExternalIP {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
604
pkg/ingress/kube/kingress/controller_test.go
Normal file
604
pkg/ingress/kube/kingress/controller_test.go
Normal file
@@ -0,0 +1,604 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 kingress
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
istiov1alpha3 "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"knative.dev/networking/pkg/apis/networking"
|
||||
"knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
ingress "knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
"knative.dev/pkg/kmeta"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/secret"
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
)
|
||||
|
||||
const (
|
||||
testNS = "testNS"
|
||||
IstioIngressClassNametest = "higress"
|
||||
)
|
||||
|
||||
var (
|
||||
ingressRules = []v1alpha1.IngressRule{{
|
||||
Hosts: []string{
|
||||
"host-tls.example.com",
|
||||
},
|
||||
HTTP: &v1alpha1.HTTPIngressRuleValue{
|
||||
Paths: []v1alpha1.HTTPIngressPath{{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: testNS,
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Visibility: v1alpha1.IngressVisibilityExternalIP,
|
||||
}, {
|
||||
Hosts: []string{
|
||||
"host-tls.test-ns.svc.cluster.local",
|
||||
},
|
||||
HTTP: &v1alpha1.HTTPIngressRuleValue{
|
||||
Paths: []v1alpha1.HTTPIngressPath{{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: testNS,
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Visibility: v1alpha1.IngressVisibilityClusterLocal,
|
||||
}}
|
||||
|
||||
ingressTLS = []v1alpha1.IngressTLS{{
|
||||
Hosts: []string{"host-tls.example.com"},
|
||||
SecretName: "secret0",
|
||||
SecretNamespace: "istio-system",
|
||||
}}
|
||||
|
||||
// The gateway server according to ingressTLS.
|
||||
ingressTLSServer = &istiov1alpha3.Server{
|
||||
Hosts: []string{"host-tls.example.com"},
|
||||
Port: &istiov1alpha3.Port{
|
||||
Name: "test-ns/reconciling-ingress:0",
|
||||
Number: 443,
|
||||
Protocol: "HTTPS",
|
||||
},
|
||||
Tls: &istiov1alpha3.ServerTLSSettings{
|
||||
Mode: istiov1alpha3.ServerTLSSettings_SIMPLE,
|
||||
ServerCertificate: "tls.crt",
|
||||
PrivateKey: "tls.key",
|
||||
CredentialName: "secret0",
|
||||
},
|
||||
}
|
||||
|
||||
ingressHTTPServer = &istiov1alpha3.Server{
|
||||
Hosts: []string{"host-tls.example.com"},
|
||||
Port: &istiov1alpha3.Port{
|
||||
Name: "http-server",
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
}
|
||||
|
||||
ingressHTTPRedirectServer = &istiov1alpha3.Server{
|
||||
Hosts: []string{"*"},
|
||||
Port: &istiov1alpha3.Port{
|
||||
Name: "http-server",
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
Tls: &istiov1alpha3.ServerTLSSettings{
|
||||
HttpsRedirect: true,
|
||||
},
|
||||
}
|
||||
|
||||
// The gateway server irrelevant to ingressTLS.
|
||||
irrelevantServer = &istiov1alpha3.Server{
|
||||
Hosts: []string{"host-tls.example.com", "host-tls.test-ns.svc.cluster.local"},
|
||||
Port: &istiov1alpha3.Port{
|
||||
Name: "test:0",
|
||||
Number: 443,
|
||||
Protocol: "HTTPS",
|
||||
},
|
||||
Tls: &istiov1alpha3.ServerTLSSettings{
|
||||
Mode: istiov1alpha3.ServerTLSSettings_SIMPLE,
|
||||
ServerCertificate: "tls.crt",
|
||||
PrivateKey: "tls.key",
|
||||
CredentialName: "other-secret",
|
||||
},
|
||||
}
|
||||
irrelevantServer1 = &istiov1alpha3.Server{
|
||||
Hosts: []string{"*"},
|
||||
Port: &istiov1alpha3.Port{
|
||||
Name: "http-server",
|
||||
Number: 80,
|
||||
Protocol: "HTTP",
|
||||
},
|
||||
}
|
||||
|
||||
deletionTime = metav1.NewTime(time.Unix(1e9, 0))
|
||||
)
|
||||
|
||||
func TestKIngressControllerConventions(t *testing.T) {
|
||||
fakeClient := kube.NewFakeClient()
|
||||
localKubeClient, client := fakeClient, fakeClient
|
||||
|
||||
options := common.Options{IngressClass: "mse", ClusterId: "", EnableStatus: true}
|
||||
|
||||
secretController := secret.NewController(localKubeClient, options.ClusterId)
|
||||
ingressController := NewController(localKubeClient, client, options, secretController)
|
||||
|
||||
testcases := map[string]func(*testing.T, common.KIngressController){
|
||||
"test convert HTTPRoute": testConvertHTTPRoute,
|
||||
}
|
||||
for name, tc := range testcases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tc(t, ingressController)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testConvertHTTPRoute(t *testing.T, c common.KIngressController) {
|
||||
testcases := []struct {
|
||||
description string
|
||||
input struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}
|
||||
expectNoError bool
|
||||
}{
|
||||
{
|
||||
description: "convertOptions is nil",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: nil,
|
||||
wrapperConfig: nil,
|
||||
},
|
||||
expectNoError: false,
|
||||
}, {
|
||||
description: "convertOptions is not nil but empty",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: &common.ConvertOptions{},
|
||||
wrapperConfig: &common.WrapperConfig{
|
||||
Config: &config.Config{},
|
||||
AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expectNoError: false,
|
||||
}, {
|
||||
description: "valid httpRoute convention,invalid backend",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: &common.ConvertOptions{
|
||||
IngressDomainCache: &common.IngressDomainCache{
|
||||
Valid: make(map[string]*common.IngressDomainBuilder),
|
||||
Invalid: make([]model.IngressDomain, 0),
|
||||
},
|
||||
Route2Ingress: map[string]*common.WrapperConfigWithRuleKey{},
|
||||
VirtualServices: make(map[string]*common.WrapperVirtualService),
|
||||
Gateways: make(map[string]*common.WrapperGateway),
|
||||
IngressRouteCache: &common.IngressRouteCache{},
|
||||
HTTPRoutes: make(map[string][]*common.WrapperHTTPRoute),
|
||||
},
|
||||
wrapperConfig: &common.WrapperConfig{Config: &config.Config{
|
||||
Spec: ingress.IngressSpec{Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{
|
||||
"host-tls.example.com",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{},
|
||||
Percent: 100,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test1", "test2"},
|
||||
SecretName: "test",
|
||||
},
|
||||
}},
|
||||
}, AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expectNoError: true,
|
||||
}, {
|
||||
description: "valid httpRoute convention,invalid split",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: &common.ConvertOptions{
|
||||
IngressDomainCache: &common.IngressDomainCache{
|
||||
Valid: make(map[string]*common.IngressDomainBuilder),
|
||||
Invalid: make([]model.IngressDomain, 0),
|
||||
},
|
||||
Route2Ingress: map[string]*common.WrapperConfigWithRuleKey{},
|
||||
VirtualServices: make(map[string]*common.WrapperVirtualService),
|
||||
Gateways: make(map[string]*common.WrapperGateway),
|
||||
IngressRouteCache: &common.IngressRouteCache{},
|
||||
HTTPRoutes: make(map[string][]*common.WrapperHTTPRoute),
|
||||
},
|
||||
wrapperConfig: &common.WrapperConfig{Config: &config.Config{
|
||||
Spec: ingress.IngressSpec{Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{
|
||||
"host-tls.example.com",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Splits: []ingress.IngressBackendSplit{{}},
|
||||
}},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test1", "test2"},
|
||||
SecretName: "test",
|
||||
},
|
||||
}},
|
||||
}, AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expectNoError: true,
|
||||
},
|
||||
{
|
||||
description: "valid httpRoute convention, vaild ingress",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: &common.ConvertOptions{
|
||||
IngressDomainCache: &common.IngressDomainCache{
|
||||
Valid: make(map[string]*common.IngressDomainBuilder),
|
||||
Invalid: make([]model.IngressDomain, 0),
|
||||
},
|
||||
Route2Ingress: map[string]*common.WrapperConfigWithRuleKey{},
|
||||
VirtualServices: make(map[string]*common.WrapperVirtualService),
|
||||
Gateways: make(map[string]*common.WrapperGateway),
|
||||
IngressRouteCache: common.NewIngressRouteCache(),
|
||||
HTTPRoutes: make(map[string][]*common.WrapperHTTPRoute),
|
||||
},
|
||||
wrapperConfig: &common.WrapperConfig{Config: &config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "host-tls-test",
|
||||
Namespace: testNS,
|
||||
},
|
||||
Spec: ingress.IngressSpec{Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{
|
||||
"host-tls.example.com",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: testNS,
|
||||
ServiceName: "v1-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test1", "test2"},
|
||||
SecretName: "test",
|
||||
},
|
||||
}},
|
||||
}, AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expectNoError: true,
|
||||
}, {
|
||||
description: "valid httpRoute convention, Spec Rule All open Ingress",
|
||||
input: struct {
|
||||
options *common.ConvertOptions
|
||||
wrapperConfig *common.WrapperConfig
|
||||
}{
|
||||
options: &common.ConvertOptions{
|
||||
IngressDomainCache: &common.IngressDomainCache{
|
||||
Valid: make(map[string]*common.IngressDomainBuilder),
|
||||
Invalid: make([]model.IngressDomain, 0),
|
||||
},
|
||||
Route2Ingress: map[string]*common.WrapperConfigWithRuleKey{},
|
||||
VirtualServices: make(map[string]*common.WrapperVirtualService),
|
||||
Gateways: make(map[string]*common.WrapperGateway),
|
||||
IngressRouteCache: common.NewIngressRouteCache(),
|
||||
HTTPRoutes: make(map[string][]*common.WrapperHTTPRoute),
|
||||
},
|
||||
wrapperConfig: &common.WrapperConfig{Config: &config.Config{
|
||||
Meta: config.Meta{
|
||||
Name: "host-kingress-all-open-test",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: ingress.IngressSpec{Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{
|
||||
"hello.default",
|
||||
"hello.default.svc",
|
||||
"hello.default.svc.cluster.local",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Path: "/pet/",
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
AppendHeaders: map[string]string{
|
||||
"Knative-Serving-Namespace": "default",
|
||||
"Knative-Serving-Revision": "hello-00002",
|
||||
},
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "default",
|
||||
ServiceName: "hello-00002",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 90,
|
||||
}, {
|
||||
AppendHeaders: map[string]string{
|
||||
"Knative-Serving-Namespace": "default",
|
||||
"Knative-Serving-Revision": "hello-00001",
|
||||
},
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "default",
|
||||
ServiceName: "hello-00001",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 10,
|
||||
}},
|
||||
AppendHeaders: map[string]string{
|
||||
"ugh": "blah",
|
||||
},
|
||||
}},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityClusterLocal,
|
||||
}, {
|
||||
Hosts: []string{
|
||||
"hello.default.zwj.com",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
AppendHeaders: map[string]string{
|
||||
"Knative-Serving-Namespace": "default",
|
||||
"Knative-Serving-Revision": "hello-00002",
|
||||
},
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "default",
|
||||
ServiceName: "hello-00002",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 90,
|
||||
}, {
|
||||
AppendHeaders: map[string]string{
|
||||
"Knative-Serving-Namespace": "default",
|
||||
"Knative-Serving-Revision": "hello-00001",
|
||||
},
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "default",
|
||||
ServiceName: "hello-00001",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 10,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Visibility: ingress.IngressVisibilityExternalIP,
|
||||
},
|
||||
},
|
||||
TLS: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test1", "test2"},
|
||||
SecretName: "test",
|
||||
},
|
||||
}},
|
||||
}, AnnotationsConfig: &annotations.Ingress{},
|
||||
},
|
||||
},
|
||||
expectNoError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testcase := range testcases {
|
||||
err := c.ConvertHTTPRoute(testcase.input.options, testcase.input.wrapperConfig)
|
||||
if err != nil {
|
||||
require.Equal(t, testcase.expectNoError, false)
|
||||
} else {
|
||||
require.Equal(t, testcase.expectNoError, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractTLSSecretName(t *testing.T) {
|
||||
testcases := []struct {
|
||||
input struct {
|
||||
host string
|
||||
tls []ingress.IngressTLS
|
||||
}
|
||||
expect string
|
||||
description string
|
||||
}{
|
||||
{
|
||||
input: struct {
|
||||
host string
|
||||
tls []ingress.IngressTLS
|
||||
}{
|
||||
host: "",
|
||||
tls: nil,
|
||||
},
|
||||
expect: "",
|
||||
description: "both are nil",
|
||||
},
|
||||
{
|
||||
input: struct {
|
||||
host string
|
||||
tls []ingress.IngressTLS
|
||||
}{
|
||||
host: "test",
|
||||
tls: []ingress.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"test"},
|
||||
SecretName: "test-secret",
|
||||
},
|
||||
{
|
||||
Hosts: []string{"test1"},
|
||||
SecretName: "test1-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "test-secret",
|
||||
description: "found secret name",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testcase := range testcases {
|
||||
actual := extractTLSSecretName(testcase.input.host, testcase.input.tls)
|
||||
require.Equal(t, testcase.expect, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldProcessIngressUpdate(t *testing.T) {
|
||||
c := controller{
|
||||
options: common.Options{},
|
||||
ingresses: make(map[string]*ingress.Ingress),
|
||||
}
|
||||
ingress1 := &ingress.Ingress{
|
||||
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-1",
|
||||
},
|
||||
Spec: ingress.IngressSpec{
|
||||
Rules: []ingress.IngressRule{
|
||||
{
|
||||
Hosts: []string{
|
||||
"host-tls.example.com",
|
||||
},
|
||||
HTTP: &ingress.HTTPIngressRuleValue{
|
||||
Paths: []ingress.HTTPIngressPath{{
|
||||
Splits: []ingress.IngressBackendSplit{{
|
||||
IngressBackend: ingress.IngressBackend{
|
||||
ServiceNamespace: "testNs",
|
||||
ServiceName: "test-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
addAnnotations(ingress1, map[string]string{networking.IngressClassAnnotationKey: IstioIngressClassNametest})
|
||||
|
||||
should, _ := c.shouldProcessIngressUpdate(ingress1)
|
||||
if !should {
|
||||
t.Fatal("should be true")
|
||||
}
|
||||
|
||||
ingress2 := *ingress1
|
||||
should, _ = c.shouldProcessIngressUpdate(&ingress2)
|
||||
if should {
|
||||
t.Fatal("should be false")
|
||||
}
|
||||
|
||||
ingress3 := *ingress1
|
||||
ingress3.Annotations = map[string]string{
|
||||
"test": "true",
|
||||
}
|
||||
should, _ = c.shouldProcessIngressUpdate(&ingress3)
|
||||
if !should {
|
||||
t.Fatal("should be true")
|
||||
}
|
||||
ingress4 := ingress1.DeepCopy()
|
||||
addAnnotations(ingress4, map[string]string{networking.IngressClassAnnotationKey: "fake-classname"})
|
||||
should, _ = c.shouldProcessIngressUpdate(ingress4)
|
||||
if should {
|
||||
t.Fatal("should be false")
|
||||
}
|
||||
//可能有坑,annotation更新可能会引起ingress资源的反复处理。
|
||||
|
||||
}
|
||||
|
||||
func addAnnotations(ing *ingress.Ingress, annos map[string]string) *ingress.Ingress {
|
||||
// UnionMaps(a, b) where value from b wins. Use annos for second arg.
|
||||
ing.ObjectMeta.Annotations = kmeta.UnionMaps(ing.ObjectMeta.Annotations, annos)
|
||||
return ing
|
||||
}
|
||||
|
||||
func TestCreateRuleKey(t *testing.T) {
|
||||
sep := "\n\n"
|
||||
wrapperHttpRoute := &common.WrapperHTTPRoute{
|
||||
Host: "higress.com",
|
||||
OriginPathType: common.Prefix,
|
||||
OriginPath: "/foo",
|
||||
}
|
||||
|
||||
annots := annotations.Annotations{
|
||||
buildHigressAnnotationKey(annotations.MatchMethod): "GET PUT",
|
||||
buildHigressAnnotationKey("exact-" + annotations.MatchHeader + "-abc"): "123",
|
||||
buildHigressAnnotationKey("prefix-" + annotations.MatchHeader + "-def"): "456",
|
||||
buildHigressAnnotationKey("exact-" + annotations.MatchQuery + "-region"): "beijing",
|
||||
buildHigressAnnotationKey("prefix-" + annotations.MatchQuery + "-user-id"): "user-",
|
||||
}
|
||||
expect := "higress.com-prefix-/foo" + sep + //host-pathType-path
|
||||
"GET PUT" + sep + // method
|
||||
"exact-abc\t123" + "\n" + "prefix-def\t456" + sep + // header
|
||||
"exact-region\tbeijing" + "\n" + "prefix-user-id\tuser-" + sep // params
|
||||
|
||||
key := createRuleKey(annots, wrapperHttpRoute.PathFormat())
|
||||
if diff := cmp.Diff(expect, key); diff != "" {
|
||||
|
||||
t.Errorf("CreateRuleKey() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func buildHigressAnnotationKey(key string) string {
|
||||
return annotations.HigressAnnotationsPrefix + "/" + key
|
||||
}
|
||||
19
pkg/ingress/kube/kingress/resources/doc.go
Normal file
19
pkg/ingress/kube/kingress/resources/doc.go
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2019 The Knative Authors
|
||||
|
||||
Licensed 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 resources holds simple functions for synthesizing child resources from
|
||||
// an Ingress resource and any relevant Ingress controller configuration.
|
||||
package resources
|
||||
148
pkg/ingress/kube/kingress/resources/virtual_service.go
Normal file
148
pkg/ingress/kube/kingress/resources/virtual_service.go
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2019 The Knative Authors
|
||||
|
||||
Licensed 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 resources
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
istiov1alpha3 "istio.io/api/networking/v1alpha3"
|
||||
"knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
"knative.dev/pkg/network"
|
||||
)
|
||||
|
||||
func MakeVirtualServiceRoute(hosts sets.String, http *v1alpha1.HTTPIngressPath) *istiov1alpha3.HTTPRoute {
|
||||
matches := []*istiov1alpha3.HTTPMatchRequest{}
|
||||
// Deduplicate hosts to avoid excessive matches, which cause a combinatorial expansion in Istio
|
||||
|
||||
for _, host := range hosts.List() {
|
||||
matches = append(matches, makeMatch(host, http.Path, http.Headers))
|
||||
}
|
||||
|
||||
weights := []*istiov1alpha3.HTTPRouteDestination{}
|
||||
for _, split := range http.Splits {
|
||||
var h *istiov1alpha3.Headers
|
||||
if len(split.AppendHeaders) > 0 {
|
||||
h = &istiov1alpha3.Headers{
|
||||
Request: &istiov1alpha3.Headers_HeaderOperations{
|
||||
Set: split.AppendHeaders,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
weights = append(weights, &istiov1alpha3.HTTPRouteDestination{
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: network.GetServiceHostname(
|
||||
split.ServiceName, split.ServiceNamespace),
|
||||
Port: &istiov1alpha3.PortSelector{
|
||||
Number: uint32(split.ServicePort.IntValue()),
|
||||
},
|
||||
},
|
||||
Weight: int32(split.Percent),
|
||||
Headers: h,
|
||||
})
|
||||
}
|
||||
|
||||
var h *istiov1alpha3.Headers
|
||||
if len(http.AppendHeaders) > 0 {
|
||||
h = &istiov1alpha3.Headers{
|
||||
Request: &istiov1alpha3.Headers_HeaderOperations{
|
||||
Set: http.AppendHeaders,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var rewrite *istiov1alpha3.HTTPRewrite
|
||||
if http.RewriteHost != "" {
|
||||
rewrite = &istiov1alpha3.HTTPRewrite{
|
||||
Authority: http.RewriteHost,
|
||||
}
|
||||
}
|
||||
|
||||
route := &istiov1alpha3.HTTPRoute{
|
||||
Retries: &istiov1alpha3.HTTPRetry{}, // Override default istio behaviour of retrying twice.
|
||||
Match: matches,
|
||||
Route: weights,
|
||||
Rewrite: rewrite,
|
||||
Headers: h,
|
||||
}
|
||||
return route
|
||||
}
|
||||
|
||||
// getDistinctHostPrefixes deduplicate a set of prefix matches. For example, the set {a, aabb} can be
|
||||
// reduced to {a}, as a prefix match on {a} accepts all the same inputs as {a, aabb}.
|
||||
func getDistinctHostPrefixes(hosts sets.String) sets.String {
|
||||
// First we sort the list. This ensures that we always process the smallest elements (which match against
|
||||
// the most patterns, as they are less specific) first.
|
||||
all := hosts.List()
|
||||
ns := sets.NewString()
|
||||
for _, h := range all {
|
||||
prefixExists := false
|
||||
h = hostPrefix(h)
|
||||
// For each element, check if any existing elements are a prefix. We only insert if none are
|
||||
// // For example, if we already have {a} and we are looking at "ab", we would not add it as it has a prefix of "a"
|
||||
for e := range ns {
|
||||
if strings.HasPrefix(h, e) {
|
||||
prefixExists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !prefixExists {
|
||||
ns.Insert(h)
|
||||
}
|
||||
}
|
||||
return ns
|
||||
}
|
||||
|
||||
func makeMatch(host, path string, headers map[string]v1alpha1.HeaderMatch) *istiov1alpha3.HTTPMatchRequest {
|
||||
match := &istiov1alpha3.HTTPMatchRequest{
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
// Do not use Regex as Istio 1.4 or later has 100 bytes limitation.
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: host},
|
||||
},
|
||||
}
|
||||
// Empty path is considered match all path. We only need to consider path
|
||||
// when it's non-empty.
|
||||
if path != "" {
|
||||
match.Uri = &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: path},
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range headers {
|
||||
match.Headers = map[string]*istiov1alpha3.StringMatch{
|
||||
k: {
|
||||
MatchType: &istiov1alpha3.StringMatch_Exact{
|
||||
Exact: v.Exact,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
// hostPrefix returns an host to match either host or host:<any port>.
|
||||
// For clusterLocalHost, it trims .svc.<local domain> from the host to match short host.
|
||||
func hostPrefix(host string) string {
|
||||
localDomainSuffix := ".svc." + network.GetClusterDomainName()
|
||||
if !strings.HasSuffix(host, localDomainSuffix) {
|
||||
return host
|
||||
}
|
||||
return strings.TrimSuffix(host, localDomainSuffix)
|
||||
}
|
||||
258
pkg/ingress/kube/kingress/resources/virtual_service_test.go
Normal file
258
pkg/ingress/kube/kingress/resources/virtual_service_test.go
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
Copyright 2019 The Knative Authors.
|
||||
|
||||
Licensed 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 resources
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"google.golang.org/protobuf/testing/protocmp"
|
||||
istiov1alpha3 "istio.io/api/networking/v1alpha3"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
"knative.dev/pkg/system"
|
||||
_ "knative.dev/pkg/system/testing"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultIngressRuleValue = &v1alpha1.HTTPIngressRuleValue{
|
||||
Paths: []v1alpha1.HTTPIngressPath{{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
Percent: 100,
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "test",
|
||||
ServiceName: "test.svc.cluster.local",
|
||||
ServicePort: intstr.FromInt(8080),
|
||||
},
|
||||
}},
|
||||
}},
|
||||
}
|
||||
defaultIngress = v1alpha1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-ingress",
|
||||
Namespace: system.Namespace(),
|
||||
},
|
||||
Spec: v1alpha1.IngressSpec{Rules: []v1alpha1.IngressRule{{
|
||||
Hosts: []string{
|
||||
"test-route.test-ns.svc.cluster.local",
|
||||
},
|
||||
HTTP: defaultIngressRuleValue,
|
||||
}}},
|
||||
}
|
||||
defaultVSCmpOpts = protocmp.Transform()
|
||||
)
|
||||
|
||||
func TestMakeVirtualServiceRoute_RewriteHost(t *testing.T) {
|
||||
ingressPath := &v1alpha1.HTTPIngressPath{
|
||||
RewriteHost: "the.target.host",
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
Percent: 100,
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceName: "the-svc",
|
||||
ServiceNamespace: "the-ns",
|
||||
ServicePort: intstr.FromInt(8080),
|
||||
},
|
||||
}},
|
||||
}
|
||||
route := MakeVirtualServiceRoute(sets.NewString("a.vanity.url", "another.vanity.url"), ingressPath)
|
||||
expected := &istiov1alpha3.HTTPRoute{
|
||||
Retries: &istiov1alpha3.HTTPRetry{},
|
||||
Match: []*istiov1alpha3.HTTPMatchRequest{{
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `a.vanity.url`},
|
||||
},
|
||||
}, {
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `another.vanity.url`},
|
||||
},
|
||||
}},
|
||||
Rewrite: &istiov1alpha3.HTTPRewrite{
|
||||
Authority: "the.target.host",
|
||||
},
|
||||
Route: []*istiov1alpha3.HTTPRouteDestination{{
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: "the-svc.the-ns.svc.cluster.local",
|
||||
Port: &istiov1alpha3.PortSelector{
|
||||
Number: 8080,
|
||||
},
|
||||
},
|
||||
Weight: 100,
|
||||
}},
|
||||
}
|
||||
if diff := cmp.Diff(expected, route, defaultVSCmpOpts); diff != "" {
|
||||
t.Error("Unexpected route (-want +got):", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// One active target.
|
||||
func TestMakeVirtualServiceRoute_Vanilla(t *testing.T) {
|
||||
ingressPath := &v1alpha1.HTTPIngressPath{
|
||||
Headers: map[string]v1alpha1.HeaderMatch{
|
||||
"my-header": {
|
||||
Exact: "my-header-value",
|
||||
},
|
||||
},
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "test-ns",
|
||||
ServiceName: "revision-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}
|
||||
route := MakeVirtualServiceRoute(sets.NewString("a.com", "b.org"), ingressPath)
|
||||
expected := &istiov1alpha3.HTTPRoute{
|
||||
Retries: &istiov1alpha3.HTTPRetry{},
|
||||
Match: []*istiov1alpha3.HTTPMatchRequest{{
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `a.com`},
|
||||
},
|
||||
Headers: map[string]*istiov1alpha3.StringMatch{
|
||||
"my-header": {
|
||||
MatchType: &istiov1alpha3.StringMatch_Exact{
|
||||
Exact: "my-header-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `b.org`},
|
||||
},
|
||||
Headers: map[string]*istiov1alpha3.StringMatch{
|
||||
"my-header": {
|
||||
MatchType: &istiov1alpha3.StringMatch_Exact{
|
||||
Exact: "my-header-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
Route: []*istiov1alpha3.HTTPRouteDestination{{
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: "revision-service.test-ns.svc.cluster.local",
|
||||
Port: &istiov1alpha3.PortSelector{Number: 80},
|
||||
},
|
||||
Weight: 100,
|
||||
}},
|
||||
}
|
||||
if diff := cmp.Diff(expected, route, defaultVSCmpOpts); diff != "" {
|
||||
t.Error("Unexpected route (-want +got):", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// One active target.
|
||||
func TestMakeVirtualServiceRoute_Internal(t *testing.T) {
|
||||
ingressPath := &v1alpha1.HTTPIngressPath{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "test-ns",
|
||||
ServiceName: "revision-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 100,
|
||||
}},
|
||||
}
|
||||
route := MakeVirtualServiceRoute(sets.NewString("a.default"), ingressPath)
|
||||
expected := &istiov1alpha3.HTTPRoute{
|
||||
Retries: &istiov1alpha3.HTTPRetry{},
|
||||
Match: []*istiov1alpha3.HTTPMatchRequest{{
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `a.default`},
|
||||
},
|
||||
}},
|
||||
Route: []*istiov1alpha3.HTTPRouteDestination{{
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: "revision-service.test-ns.svc.cluster.local",
|
||||
Port: &istiov1alpha3.PortSelector{Number: 80},
|
||||
},
|
||||
Weight: 100,
|
||||
}},
|
||||
}
|
||||
if diff := cmp.Diff(expected, route, defaultVSCmpOpts); diff != "" {
|
||||
t.Error("Unexpected route (-want +got):", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// Two active targets.
|
||||
func TestMakeVirtualServiceRoute_TwoTargets(t *testing.T) {
|
||||
ingressPath := &v1alpha1.HTTPIngressPath{
|
||||
Splits: []v1alpha1.IngressBackendSplit{{
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "test-ns",
|
||||
ServiceName: "revision-service",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
Percent: 90,
|
||||
}, {
|
||||
IngressBackend: v1alpha1.IngressBackend{
|
||||
ServiceNamespace: "test-ns",
|
||||
ServiceName: "new-revision-service",
|
||||
ServicePort: intstr.FromInt(81),
|
||||
},
|
||||
Percent: 10,
|
||||
}},
|
||||
}
|
||||
route := MakeVirtualServiceRoute(sets.NewString("test.org"), ingressPath)
|
||||
expected := &istiov1alpha3.HTTPRoute{
|
||||
Retries: &istiov1alpha3.HTTPRetry{},
|
||||
Match: []*istiov1alpha3.HTTPMatchRequest{{
|
||||
Authority: &istiov1alpha3.StringMatch{
|
||||
MatchType: &istiov1alpha3.StringMatch_Prefix{Prefix: `test.org`},
|
||||
},
|
||||
}},
|
||||
Route: []*istiov1alpha3.HTTPRouteDestination{{
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: "revision-service.test-ns.svc.cluster.local",
|
||||
Port: &istiov1alpha3.PortSelector{Number: 80},
|
||||
},
|
||||
Weight: 90,
|
||||
}, {
|
||||
Destination: &istiov1alpha3.Destination{
|
||||
Host: "new-revision-service.test-ns.svc.cluster.local",
|
||||
Port: &istiov1alpha3.PortSelector{Number: 81},
|
||||
},
|
||||
Weight: 10,
|
||||
}},
|
||||
}
|
||||
if diff := cmp.Diff(expected, route, defaultVSCmpOpts); diff != "" {
|
||||
t.Error("Unexpected route (-want +got):", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDistinctHostPrefixes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
in sets.String
|
||||
out sets.String
|
||||
}{
|
||||
{"empty", sets.NewString(), sets.NewString()},
|
||||
{"single element", sets.NewString("a"), sets.NewString("a")},
|
||||
{"no overlap", sets.NewString("a", "b"), sets.NewString("a", "b")},
|
||||
{"overlap", sets.NewString("a", "ab", "abc"), sets.NewString("a")},
|
||||
{"multiple overlaps", sets.NewString("a", "ab", "abc", "xyz", "xy", "m"), sets.NewString("a", "xy", "m")},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := getDistinctHostPrefixes(tt.in)
|
||||
if !tt.out.Equal(got) {
|
||||
t.Fatalf("Expected %v, got %v", tt.out, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
127
pkg/ingress/kube/kingress/status.go
Normal file
127
pkg/ingress/kube/kingress/status.go
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 kingress
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
coreV1 "k8s.io/api/core/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
listerv1 "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
kingressclient "knative.dev/networking/pkg/client/clientset/versioned"
|
||||
kingresslister "knative.dev/networking/pkg/client/listers/networking/v1alpha1"
|
||||
|
||||
common2 "github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
)
|
||||
|
||||
// statusSyncer keeps the status IP in each Ingress resource updated
|
||||
type statusSyncer struct {
|
||||
client kingressclient.Interface
|
||||
controller *controller
|
||||
watchedNamespace string
|
||||
ingressLister kingresslister.IngressLister
|
||||
serviceLister listerv1.ServiceLister
|
||||
}
|
||||
|
||||
// newStatusSyncer creates a new instance
|
||||
func newStatusSyncer(localKubeClient, client kube.Client, controller *controller, namespace string) *statusSyncer {
|
||||
return &statusSyncer{
|
||||
client: client.KIngress(),
|
||||
controller: controller,
|
||||
watchedNamespace: namespace,
|
||||
ingressLister: client.KIngressInformer().Networking().V1alpha1().Ingresses().Lister(),
|
||||
serviceLister: localKubeClient.KubeInformer().Core().V1().Services().Lister(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statusSyncer) run(stopCh <-chan struct{}) {
|
||||
cache.WaitForCacheSync(stopCh, s.controller.HasSynced)
|
||||
|
||||
ticker := time.NewTicker(common2.DefaultStatusUpdateInterval)
|
||||
for {
|
||||
select {
|
||||
case <-stopCh:
|
||||
ticker.Stop()
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := s.runUpdateStatus(); err != nil {
|
||||
IngressLog.Errorf("update status task fail, err %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statusSyncer) runUpdateStatus() error {
|
||||
svcList, err := s.serviceLister.Services(s.watchedNamespace).List(common2.SvcLabelSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
IngressLog.Debugf("found number %d of svc", len(svcList))
|
||||
lbStatusList := common2.GetLbStatusList(svcList)
|
||||
return s.updateStatus(lbStatusList)
|
||||
}
|
||||
|
||||
func transportLoadBalancerIngress(status []coreV1.LoadBalancerIngress) []v1alpha1.LoadBalancerIngressStatus {
|
||||
var KnativeLBIngress []v1alpha1.LoadBalancerIngressStatus
|
||||
for _, addr := range status {
|
||||
KnativeIng := v1alpha1.LoadBalancerIngressStatus{
|
||||
IP: addr.IP,
|
||||
Domain: addr.Hostname,
|
||||
}
|
||||
KnativeLBIngress = append(KnativeLBIngress, KnativeIng)
|
||||
}
|
||||
return KnativeLBIngress
|
||||
}
|
||||
|
||||
// updateStatus updates ingress status with the list of IP
|
||||
func (s *statusSyncer) updateStatus(status []coreV1.LoadBalancerIngress) error {
|
||||
ingressList, err := s.ingressLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ingress := range ingressList {
|
||||
shouldTarget, err := s.controller.shouldProcessIngress(ingress)
|
||||
if err != nil {
|
||||
IngressLog.Warnf("error determining whether should target ingress %s/%s within cluster %s for status update: %v",
|
||||
ingress.Namespace, ingress.Name, s.controller.options.ClusterId, err)
|
||||
return err
|
||||
}
|
||||
if !shouldTarget {
|
||||
continue
|
||||
}
|
||||
ingress.Status.MarkNetworkConfigured()
|
||||
KIngressStatus := transportLoadBalancerIngress(status)
|
||||
if ingress.Status.PublicLoadBalancer == nil || len(ingress.Status.PublicLoadBalancer.Ingress) != len(KIngressStatus) || reflect.DeepEqual(ingress.Status.PublicLoadBalancer.Ingress, KIngressStatus) {
|
||||
ingress.Status.ObservedGeneration = ingress.Generation
|
||||
ingress.Status.MarkLoadBalancerReady(KIngressStatus, KIngressStatus)
|
||||
IngressLog.Infof("Update Ingress %v/%v within cluster %s status", ingress.Namespace, ingress.Name, s.controller.options.ClusterId)
|
||||
}
|
||||
_, err = s.client.NetworkingV1alpha1().Ingresses(ingress.Namespace).UpdateStatus(context.TODO(), ingress, metaV1.UpdateOptions{})
|
||||
if err != nil {
|
||||
IngressLog.Warnf("error updating ingress %s/%s within cluster %s status: %v",
|
||||
ingress.Namespace, ingress.Name, s.controller.options.ClusterId, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
204
pkg/ingress/translation/translation.go
Normal file
204
pkg/ingress/translation/translation.go
Normal file
@@ -0,0 +1,204 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package translation
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
ingressconfig "github.com/alibaba/higress/pkg/ingress/config"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
"github.com/alibaba/higress/pkg/kube"
|
||||
)
|
||||
|
||||
var (
|
||||
_ model.ConfigStoreCache = &IngressTranslation{}
|
||||
_ model.IngressStore = &IngressTranslation{}
|
||||
)
|
||||
|
||||
type IngressTranslation struct {
|
||||
ingressConfig *ingressconfig.IngressConfig
|
||||
kingressConfig *ingressconfig.KIngressConfig
|
||||
mutex sync.RWMutex
|
||||
higressRouteCache model.IngressRouteCollection
|
||||
higressDomainCache model.IngressDomainCollection
|
||||
}
|
||||
|
||||
func NewIngressTranslation(localKubeClient kube.Client, XDSUpdater model.XDSUpdater, namespace, clusterId string) *IngressTranslation {
|
||||
if clusterId == "Kubernetes" {
|
||||
clusterId = ""
|
||||
}
|
||||
Config := &IngressTranslation{
|
||||
ingressConfig: ingressconfig.NewIngressConfig(localKubeClient, XDSUpdater, namespace, clusterId),
|
||||
kingressConfig: ingressconfig.NewKIngressConfig(localKubeClient, XDSUpdater, namespace, clusterId),
|
||||
}
|
||||
return Config
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) AddLocalCluster(options common.Options) (common.IngressController, common.KIngressController) {
|
||||
if m.kingressConfig == nil {
|
||||
return m.ingressConfig.AddLocalCluster(options), nil
|
||||
}
|
||||
return m.ingressConfig.AddLocalCluster(options), m.kingressConfig.AddLocalCluster(options)
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) InitializeCluster(ingressController common.IngressController, kingressController common.KIngressController, stop <-chan struct{}) error {
|
||||
if err := m.ingressConfig.InitializeCluster(ingressController, stop); err != nil {
|
||||
return err
|
||||
}
|
||||
if kingressController == nil {
|
||||
return nil
|
||||
}
|
||||
if err := m.kingressConfig.InitializeCluster(kingressController, stop); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) RegisterEventHandler(kind config.GroupVersionKind, f model.EventHandler) {
|
||||
m.ingressConfig.RegisterEventHandler(kind, f)
|
||||
if m.kingressConfig != nil {
|
||||
m.kingressConfig.RegisterEventHandler(kind, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) HasSynced() bool {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
if !m.ingressConfig.HasSynced() {
|
||||
return false
|
||||
}
|
||||
if m.kingressConfig != nil {
|
||||
if !m.kingressConfig.HasSynced() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Run(stop <-chan struct{}) {
|
||||
go m.ingressConfig.Run(stop)
|
||||
if m.kingressConfig != nil {
|
||||
go m.kingressConfig.Run(stop)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) SetWatchErrorHandler(f func(r *cache.Reflector, err error)) error {
|
||||
m.ingressConfig.SetWatchErrorHandler(f)
|
||||
if m.kingressConfig != nil {
|
||||
m.kingressConfig.SetWatchErrorHandler(f)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) GetIngressRoutes() model.IngressRouteCollection {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
ingressRouteCache := m.ingressConfig.GetIngressRoutes()
|
||||
m.higressRouteCache = model.IngressRouteCollection{}
|
||||
m.higressRouteCache.Invalid = append(m.higressRouteCache.Invalid, ingressRouteCache.Invalid...)
|
||||
m.higressRouteCache.Valid = append(m.higressRouteCache.Valid, ingressRouteCache.Valid...)
|
||||
if m.kingressConfig != nil {
|
||||
kingressRouteCache := m.kingressConfig.GetIngressRoutes()
|
||||
m.higressRouteCache.Invalid = append(m.higressRouteCache.Invalid, kingressRouteCache.Invalid...)
|
||||
m.higressRouteCache.Valid = append(m.higressRouteCache.Valid, kingressRouteCache.Valid...)
|
||||
}
|
||||
|
||||
return m.higressRouteCache
|
||||
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) GetIngressDomains() model.IngressDomainCollection {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
ingressDomainCache := m.ingressConfig.GetIngressDomains()
|
||||
|
||||
m.higressDomainCache = model.IngressDomainCollection{}
|
||||
m.higressDomainCache.Invalid = append(m.higressDomainCache.Invalid, ingressDomainCache.Invalid...)
|
||||
m.higressDomainCache.Valid = append(m.higressDomainCache.Valid, ingressDomainCache.Valid...)
|
||||
if m.kingressConfig != nil {
|
||||
kingressDomainCache := m.kingressConfig.GetIngressDomains()
|
||||
m.higressDomainCache.Invalid = append(m.higressDomainCache.Invalid, kingressDomainCache.Invalid...)
|
||||
m.higressDomainCache.Valid = append(m.higressDomainCache.Valid, kingressDomainCache.Valid...)
|
||||
}
|
||||
return m.higressDomainCache
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Schemas() collection.Schemas {
|
||||
return common.IngressIR
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Get(typ config.GroupVersionKind, name, namespace string) *config.Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) List(typ config.GroupVersionKind, namespace string) ([]config.Config, error) {
|
||||
if typ != gvk.Gateway &&
|
||||
typ != gvk.VirtualService &&
|
||||
typ != gvk.DestinationRule &&
|
||||
typ != gvk.EnvoyFilter &&
|
||||
typ != gvk.ServiceEntry &&
|
||||
typ != gvk.WasmPlugin {
|
||||
return nil, common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
// Currently, only support list all namespaces gateways or virtualservices.
|
||||
if namespace != "" {
|
||||
IngressLog.Warnf("ingress store only support type %s of all namespace.", typ)
|
||||
return nil, common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
ingressConfig, err := m.ingressConfig.List(typ, namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var higressConfig []config.Config
|
||||
higressConfig = append(higressConfig, ingressConfig...)
|
||||
if m.kingressConfig != nil {
|
||||
kingressConfig, err := m.kingressConfig.List(typ, namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
higressConfig = append(higressConfig, kingressConfig...)
|
||||
}
|
||||
return higressConfig, nil
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Create(config config.Config) (revision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Update(config config.Config) (newRevision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) UpdateStatus(config config.Config) (newRevision string, err error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Patch(orig config.Config, patchFn config.PatchFunc) (string, error) {
|
||||
return "", common.ErrUnsupportedOp
|
||||
}
|
||||
|
||||
func (m *IngressTranslation) Delete(typ config.GroupVersionKind, name, namespace string, resourceVersion *string) error {
|
||||
return common.ErrUnsupportedOp
|
||||
}
|
||||
@@ -15,21 +15,29 @@
|
||||
package kube
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
istiokube "istio.io/istio/pkg/kube"
|
||||
apiExtensionsV1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/rest"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
kingressclient "knative.dev/networking/pkg/client/clientset/versioned"
|
||||
kingressfake "knative.dev/networking/pkg/client/clientset/versioned/fake"
|
||||
kingressinformer "knative.dev/networking/pkg/client/informers/externalversions"
|
||||
|
||||
higressclient "github.com/alibaba/higress/client/pkg/clientset/versioned"
|
||||
higressfake "github.com/alibaba/higress/client/pkg/clientset/versioned/fake"
|
||||
higressinformer "github.com/alibaba/higress/client/pkg/informers/externalversions"
|
||||
"github.com/alibaba/higress/pkg/config/constants"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
@@ -40,6 +48,11 @@ type Client interface {
|
||||
|
||||
// HigressInformer returns an informer for the higress client
|
||||
HigressInformer() higressinformer.SharedInformerFactory
|
||||
|
||||
//KIngress return the Knative kube client
|
||||
KIngress() kingressclient.Interface
|
||||
|
||||
KIngressInformer() kingressinformer.SharedInformerFactory
|
||||
}
|
||||
|
||||
type client struct {
|
||||
@@ -48,9 +61,12 @@ type client struct {
|
||||
higress higressclient.Interface
|
||||
higressInformer higressinformer.SharedInformerFactory
|
||||
|
||||
kingress kingressclient.Interface
|
||||
kingressInformer kingressinformer.SharedInformerFactory
|
||||
// If enable, will wait for cache syncs with extremely short delay. This should be used only for tests
|
||||
fastSync bool
|
||||
informerWatchesPending *atomic.Int32
|
||||
fastSync bool
|
||||
informerWatchesPending *atomic.Int32
|
||||
kinformerWatchesPending *atomic.Int32
|
||||
}
|
||||
|
||||
const resyncInterval = 0
|
||||
@@ -62,7 +78,9 @@ func NewFakeClient(objects ...runtime.Object) Client {
|
||||
c.higress = higressfake.NewSimpleClientset()
|
||||
c.higressInformer = higressinformer.NewSharedInformerFactoryWithOptions(c.higress, resyncInterval)
|
||||
c.informerWatchesPending = atomic.NewInt32(0)
|
||||
|
||||
c.kingress = kingressfake.NewSimpleClientset()
|
||||
c.kingressInformer = kingressinformer.NewSharedInformerFactoryWithOptions(c.kingress, resyncInterval)
|
||||
c.kinformerWatchesPending = atomic.NewInt32(0)
|
||||
// https://github.com/kubernetes/kubernetes/issues/95372
|
||||
// There is a race condition in the client fakes, where events that happen between the List and Watch
|
||||
// of an informer are dropped. To avoid this, we explicitly manage the list and watch, ensuring all lists
|
||||
@@ -90,6 +108,27 @@ func NewFakeClient(objects ...runtime.Object) Client {
|
||||
fc := c.higress.(*higressfake.Clientset)
|
||||
fc.PrependReactor("list", "&", listReactor)
|
||||
fc.PrependWatchReactor("*", watchReactor(fc.Tracker()))
|
||||
|
||||
klistReactor := func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
c.kinformerWatchesPending.Inc()
|
||||
return false, nil, nil
|
||||
}
|
||||
kwatchReactor := func(tracker clienttesting.ObjectTracker) func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
return func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := tracker.Watch(gvr, ns)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
c.kinformerWatchesPending.Dec()
|
||||
return true, watch, nil
|
||||
}
|
||||
}
|
||||
fcknative := c.kingress.(*kingressfake.Clientset)
|
||||
fcknative.PrependReactor("list", "&", klistReactor)
|
||||
fcknative.PrependWatchReactor("*", kwatchReactor(fcknative.Tracker()))
|
||||
|
||||
c.fastSync = true
|
||||
return c
|
||||
}
|
||||
@@ -107,9 +146,28 @@ func NewClient(clientConfig clientcmd.ClientConfig) (Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
c.higressInformer = higressinformer.NewSharedInformerFactory(c.higress, resyncInterval)
|
||||
|
||||
c.kingress, err = kingressclient.NewForConfig(istioClient.RESTConfig())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if CheckKIngressCRDExist(istioClient.RESTConfig()) {
|
||||
c.kingressInformer = kingressinformer.NewSharedInformerFactory(c.kingress, resyncInterval)
|
||||
} else {
|
||||
c.kingressInformer = nil
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (c *client) KIngress() kingressclient.Interface {
|
||||
return c.kingress
|
||||
}
|
||||
|
||||
func (c *client) KIngressInformer() kingressinformer.SharedInformerFactory {
|
||||
return c.kingressInformer
|
||||
}
|
||||
|
||||
func (c *client) Higress() higressclient.Interface {
|
||||
return c.higress
|
||||
}
|
||||
@@ -121,6 +179,7 @@ func (c *client) HigressInformer() higressinformer.SharedInformerFactory {
|
||||
func (c *client) RunAndWait(stop <-chan struct{}) {
|
||||
c.Client.RunAndWait(stop)
|
||||
c.higressInformer.Start(stop)
|
||||
|
||||
if c.fastSync {
|
||||
fastWaitForCacheSync(stop, c.higressInformer)
|
||||
_ = wait.PollImmediate(time.Microsecond*100, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
@@ -137,6 +196,27 @@ func (c *client) RunAndWait(stop <-chan struct{}) {
|
||||
} else {
|
||||
c.higressInformer.WaitForCacheSync(stop)
|
||||
}
|
||||
|
||||
if c.kingressInformer != nil {
|
||||
c.kingressInformer.Start(stop)
|
||||
if c.fastSync {
|
||||
fastWaitForCacheSync(stop, c.kingressInformer)
|
||||
_ = wait.PollImmediate(time.Microsecond*100, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
select {
|
||||
case <-stop:
|
||||
return false, fmt.Errorf("channel closed")
|
||||
default:
|
||||
}
|
||||
if c.informerWatchesPending.Load() == 0 {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
} else {
|
||||
c.kingressInformer.WaitForCacheSync(stop)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type reflectInformerSync interface {
|
||||
@@ -162,3 +242,23 @@ func fastWaitForCacheSync(stop <-chan struct{}, informerFactory reflectInformerS
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
|
||||
// Check Knative Ingress CRD
|
||||
func CheckKIngressCRDExist(config *rest.Config) bool {
|
||||
apiExtClientset, err := apiExtensionsV1.NewForConfig(config)
|
||||
if err != nil {
|
||||
fmt.Errorf("failed creating apiExtension Client: %v", err)
|
||||
return false
|
||||
}
|
||||
crdList, err := apiExtClientset.CustomResourceDefinitions().List(context.TODO(), metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
fmt.Errorf("failed listing Custom Resource Definition: %v", err)
|
||||
return false
|
||||
}
|
||||
for _, crd := range crdList.Items {
|
||||
if crd.Name == constants.KnativeIngressCRDName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user