From 1159f6478aefce79d182a011414e0fcadacbd2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 10 Jan 2023 15:06:12 +0100 Subject: [PATCH] feat: add support for single controller, multi gateway deployments --- CHANGELOG.md | 13 +- go.mod | 23 +- go.sum | 170 ++++- internal/cmd/rootcmd/env_test.go | 36 + .../controllers/gateway/gateway_controller.go | 4 +- internal/dataplane/kong_client.go | 297 +++++--- internal/dataplane/sendconfig/kong.go | 90 ++- internal/dataplane/sendconfig/sendconfig.go | 110 +-- internal/dataplane/synchronizer.go | 4 +- internal/manager/config.go | 27 +- internal/manager/run.go | 73 +- internal/manager/setup.go | 38 +- internal/manager/utils/kongconfig/root.go | 198 ++++++ .../manager/utils/kongconfig/root_test.go | 661 ++++++++++++++++++ internal/manager/utils/reports.go | 11 +- internal/util/plugin_schema_helper.go | 3 - 16 files changed, 1490 insertions(+), 268 deletions(-) create mode 100644 internal/manager/utils/kongconfig/root.go create mode 100644 internal/manager/utils/kongconfig/root_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index a4fffb165f..6e5fd72915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,13 +69,18 @@ Adding a new version? You'll need three changes: ### Added -- Store status of whether configuration succedded or failed for Kubernetes +- Store status of whether configuration succedded or failed for Kubernetes objects in dataplane client and publish the events to let controllers know - if the controlled objects succeeded or failed to be translated to Kong + if the controlled objects succeeded or failed to be translated to Kong configuration. - [#3359](https://github.com/Kong/kubernetes-ingress-controller/pull/3359) + [#3359](https://github.com/Kong/kubernetes-ingress-controller/pull/3359) - Added `version` command - [#3379](https://github.com/Kong/kubernetes-ingress-controller/pull/3379) + [#3379](https://github.com/Kong/kubernetes-ingress-controller/pull/3379) +- Added possibility to configure multiple Kong Gateways through the + `--kong-admin-url` CLI flag (which can be specified multiple times) or through + a corresponding environment variable `CONTROLLER_KONG_ADMIN_URL` (which can + specify multiple values separated by a comma). + [#3268](https://github.com/Kong/kubernetes-ingress-controller/pull/3268) ### Fixed diff --git a/go.mod b/go.mod index 9157889ba3..6e6edcf0e7 100644 --- a/go.mod +++ b/go.mod @@ -43,6 +43,18 @@ require ( sigs.k8s.io/yaml v1.3.0 ) +require ( + github.com/cockroachdb/errors v1.9.0 // indirect + github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/getsentry/sentry-go v0.13.0 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/sourcegraph/sourcegraph/lib v0.0.0-20221216004406-749998a2ac74 // indirect + go.uber.org/atomic v1.10.0 // indirect +) + require ( cloud.google.com/go/compute v1.14.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect @@ -104,11 +116,11 @@ require ( github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect @@ -128,6 +140,7 @@ require ( github.com/sergi/go-diff v1.2.0 // indirect github.com/shirou/gopsutil/v3 v3.22.11 // indirect github.com/shopspring/decimal v1.2.0 // indirect + github.com/sourcegraph/conc v0.1.0 github.com/spf13/cast v1.5.0 // indirect github.com/ssgelm/cookiejarparser v1.0.1 // indirect github.com/tidwall/gjson v1.14.4 // indirect @@ -143,12 +156,12 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.8.0 golang.org/x/crypto v0.3.0 // indirect - golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 // indirect + golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 golang.org/x/mod v0.6.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/sync v0.1.0 // indirect + golang.org/x/sync v0.1.0 golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect diff --git a/go.sum b/go.sum index 624a1d730e..39bed599f8 100644 --- a/go.sum +++ b/go.sum @@ -57,6 +57,7 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/g 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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= 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= @@ -70,6 +71,12 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Kong/go-diff v1.2.2 h1:KKKaqHc8IxuguFVIZMNt3bi6YuC/t9r7BGD8bOOpSgM= github.com/Kong/go-diff v1.2.2/go.mod h1:nlvdwVZQk3Rm+tbI0cDmKFrOjghtcZTrZBp+UruvvA8= github.com/Kong/gojsondiff v1.3.2 h1:qIOVq2mUXt+NXy8Be5gRUee9TP3Ve0MbQSafg9bXKZE= @@ -89,12 +96,14 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= 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/adrg/strutil v0.2.3 h1:WZVn3ItPBovFmP4wMHHVXUr8luRaHrbyIuLlHt32GZQ= github.com/adrg/strutil v0.2.3/go.mod h1:+SNxbiH6t+O+5SZqIj5n/9i5yUjR+S3XXVrjEcN2mxg= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= 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= @@ -104,12 +113,14 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/avast/retry-go/v4 v4.3.2 h1:x4sTEu3jSwr7zNjya8NTdIN+U88u/jtO/q3OupBoDtM= github.com/avast/retry-go/v4 v4.3.2/go.mod h1:rg6XFaiuFYII0Xu3RDbZQkxCofFwruZKW8oEF1jpWiU= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -151,15 +162,31 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.8/go.mod h1:z6VnEL3hZ/2ONZEvG7S5Ym0bU2AqPcEKnIiA1wbsSu0= +github.com/cockroachdb/errors v1.9.0 h1:B48dYem5SlAY7iU8AKsgedb4gH6mo+bDkbtLIvM/a88= +github.com/cockroachdb/errors v1.9.0/go.mod h1:vaNcEYYqbIqB5JhKBhFV9CneUqeuEbB2OYJBK4GBNYQ= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -170,7 +197,9 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= 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= @@ -189,6 +218,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m 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/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -205,6 +235,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -213,12 +244,15 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= 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= @@ -230,8 +264,15 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= 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= @@ -252,6 +293,7 @@ github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -268,14 +310,21 @@ github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/flect v0.2.4/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -313,6 +362,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 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= @@ -395,6 +445,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z 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 v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -430,6 +482,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -445,16 +498,25 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/tdigest v0.0.0-20180711151920-a7d76c6f093a/go.mod h1:9GkyshztGufsdPQWjH+ifgnIr3xNUL5syI70g2dzU1o= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= 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= @@ -468,6 +530,7 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -475,14 +538,31 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= 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= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kong/deck v1.17.1 h1:mBtd5CBv+Ouwz6SbOWfpvQvSMsiD3jwIeiKVU0oNvFI= github.com/kong/deck v1.17.1/go.mod h1:IH/Ic9dgBwvb1WHOx3+0BUzo+SYiVjd9inEe+JIIeK4= github.com/kong/go-kong v0.34.1-0.20221222170410-6c81ce561662 h1:IIIAzs6eNp+lA+E0k9oooAyqmAJyAA/9Ebyb0y19mrU= @@ -498,10 +578,14 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= @@ -509,6 +593,7 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -517,21 +602,31 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= 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.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -543,8 +638,8 @@ github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HK github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -569,12 +664,19 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -583,7 +685,9 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +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.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -609,6 +713,9 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -657,16 +764,25 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -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/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw= github.com/samber/lo v1.37.0/go.mod h1:9vaz2O4o8oOnK23pd2TrXufcbdbJIa3b6cstBWKpopA= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= @@ -687,6 +803,10 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sourcegraph/conc v0.1.0 h1:9GeYVmWWa1jeOq3zGq17m10d9pjYZpiGTj/N4hQFl58= +github.com/sourcegraph/conc v0.1.0/go.mod h1:sEXGtKMpRbfGhShfObhgMyxDpdu/5ABGrzSGYaigx5A= +github.com/sourcegraph/sourcegraph/lib v0.0.0-20221216004406-749998a2ac74 h1:4yKiBHEHJXHu9umlQzhX4sRK622p+Aw4TGvvAw9X9j8= +github.com/sourcegraph/sourcegraph/lib v0.0.0-20221216004406-749998a2ac74/go.mod h1:HCz/QYbQD5wiwRFYn5ochsMbw6ZNnSgZckE+EYLSBqw= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -694,6 +814,7 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= @@ -703,6 +824,7 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/ssgelm/cookiejarparser v1.0.1 h1:cRdXauUbOTFzTPJFaeiWbHnQ+tRGlpKKzvIK9PUekE4= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= @@ -739,7 +861,17 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 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= @@ -753,8 +885,12 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yudai/pp v2.0.2-0.20150410014804-be8315415630+incompatible h1:TmF93o7P81230DTx1l2zw5rZbsDpOOQXoKVCa8+nXXI= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -799,8 +935,9 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee33 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 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/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= 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= @@ -815,15 +952,19 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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-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-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-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -880,6 +1021,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20190327091125-710a502c58a2/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= @@ -920,6 +1062,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/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= @@ -968,6 +1111,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-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= @@ -977,7 +1121,9 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1037,9 +1183,11 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-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-20220209214540-3681064d5158/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1071,6 +1219,7 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-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= @@ -1079,11 +1228,13 @@ golang.org/x/time v0.3.0/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-20180917221912-90fa682c2a6e/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-20181221001348-537d06c36207/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-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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1191,6 +1342,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1256,6 +1408,7 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1312,9 +1465,13 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1330,6 +1487,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/cmd/rootcmd/env_test.go b/internal/cmd/rootcmd/env_test.go index 69db1c0960..0bd2e495e0 100644 --- a/internal/cmd/rootcmd/env_test.go +++ b/internal/cmd/rootcmd/env_test.go @@ -46,6 +46,42 @@ func TestBindEnvVars(t *testing.T) { assert.NoError(t, err) } +func TestBindEnvVarsSlice(t *testing.T) { + t.Run("set by flags", func(t *testing.T) { + cmd := &cobra.Command{ + PreRunE: bindEnvVars, + Run: func(cmd *cobra.Command, args []string) {}, + } + + ss := cmd.Flags().StringSlice("flag-string-slice", []string{"default"}, "No description") + + t.Setenv("CONTROLLER_FLAG_STRING_SLICE", "q,w,e,r,t,y") + + cmd.SetArgs([]string{ + "--flag-string-slice=1", + "--flag-string-slice=2", + "--flag-string-slice=3", + }) + assert.NoError(t, cmd.Execute()) + assert.Equal(t, []string{"1", "2", "3"}, *ss) + }) + + t.Run("set by env", func(t *testing.T) { + cmd := &cobra.Command{ + PreRunE: bindEnvVars, + Run: func(cmd *cobra.Command, args []string) {}, + } + + ss := cmd.Flags().StringSlice("flag-string-slice", []string{"default"}, "No description") + + t.Setenv("CONTROLLER_FLAG_STRING_SLICE", "q,w,e,r,t,y") + + cmd.SetArgs([]string{}) + assert.NoError(t, cmd.Execute()) + assert.Equal(t, []string{"q", "w", "e", "r", "t", "y"}, *ss) + }) +} + func TestBindEnvVarsValidation(t *testing.T) { cmd := &cobra.Command{ PreRunE: bindEnvVars, diff --git a/internal/controllers/gateway/gateway_controller.go b/internal/controllers/gateway/gateway_controller.go index 4493fa846d..3caba40172 100644 --- a/internal/controllers/gateway/gateway_controller.go +++ b/internal/controllers/gateway/gateway_controller.go @@ -317,7 +317,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct debug(log, gateway, "failed to delete object from data-plane, requeuing") return ctrl.Result{}, err } - debug(log, gateway, "ensured object was removed from the data-plane (if ever present)") + debug(log, gateway, "ensured gateway was removed from the data-plane (if ever present)") return ctrl.Result{}, nil } if gwc.Spec.ControllerName != ControllerName { @@ -331,7 +331,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct debug(log, gateway, "failed to delete object from data-plane, requeuing") return ctrl.Result{}, err } - debug(log, gateway, "ensured object was removed from the data-plane (if ever present)") + debug(log, gateway, "ensured gateway was removed from the data-plane (if ever present)") return ctrl.Result{}, nil } diff --git a/internal/dataplane/kong_client.go b/internal/dataplane/kong_client.go index bfe2d7eb48..0255ffffef 100644 --- a/internal/dataplane/kong_client.go +++ b/internal/dataplane/kong_client.go @@ -3,21 +3,26 @@ package dataplane import ( "context" "fmt" + "reflect" + "sort" "sync" "time" - "github.com/blang/semver/v4" "github.com/kong/deck/file" "github.com/kong/go-kong/kong" "github.com/prometheus/client_golang/prometheus" "github.com/samber/lo" "github.com/sirupsen/logrus" + "github.com/sourcegraph/conc/iter" + "golang.org/x/exp/slices" + "golang.org/x/sync/errgroup" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/deckgen" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/failures" + "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/parser" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/sendconfig" "github.com/kong/kubernetes-ingress-controller/v2/internal/metrics" @@ -78,9 +83,6 @@ type KongClient struct { // dbmode indicates the current database mode of the backend Kong Admin API dbmode string - // lastConfigSHA is a checksum of the last successful update to the data-plane - lastConfigSHA []byte - // lock is used to ensure threadsafety of the KongClient object lock sync.RWMutex @@ -120,6 +122,9 @@ type KongClient struct { // eventRecorder is used to record warning events for resource failures. eventRecorder record.EventRecorder + + // SHAs is a slice is configuration hashes send in last batch send. + SHAs []string } // NewKongClient provides a new KongClient object after connecting to the @@ -134,6 +139,7 @@ func NewKongClient( diagnostic util.ConfigDumpDiagnostic, kongConfig sendconfig.Kong, eventRecorder record.EventRecorder, + dbMode string, ) (*KongClient, error) { // build the client object cache := store.NewCacheStores() @@ -148,46 +154,9 @@ func NewKongClient( cache: &cache, kongConfig: kongConfig, eventRecorder: eventRecorder, + dbmode: dbMode, } - // download the kong root configuration (and validate connectivity to the proxy API) - root, err := c.RootWithTimeout(ctx) - if err != nil { - return nil, err - } - - // pull the proxy configuration out of the root config and validate it - proxyConfig, ok := root["configuration"].(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("invalid root configuration, expected a map[string]interface{} got %T", proxyConfig["configuration"]) - } - - // validate the database configuration for the proxy and check for supported database configurations - dbmode, ok := proxyConfig["database"].(string) - if !ok { - return nil, fmt.Errorf("invalid database configuration, expected a string got %t", proxyConfig["database"]) - } - switch dbmode { - case "off", "": - c.kongConfig.InMemory = true - case "postgres": - c.kongConfig.InMemory = false - case "cassandra": - return nil, fmt.Errorf("Cassandra-backed deployments of Kong managed by the ingress controller are no longer supported; you must migrate to a Postgres-backed or DB-less deployment") - default: - return nil, fmt.Errorf("%s is not a supported database backend", dbmode) - } - - // validate the proxy version - proxyVersion, err := kong.ParseSemanticVersion(kong.VersionFromInfo(root)) - if err != nil { - return nil, err - } - - // store the gathered configuration options - c.kongConfig.Version = semver.Version{Major: proxyVersion.Major(), Minor: proxyVersion.Minor(), Patch: proxyVersion.Patch()} - c.dbmode = dbmode - return c, nil } @@ -220,19 +189,104 @@ func (c *KongClient) ObjectExists(obj client.Object) (bool, error) { return exists, err } -// Listeners retrieves the currently configured listeners from the -// underlying proxy so that callers can gather this metadata to -// know which ports and protocols are in use by the proxy. -func (c *KongClient) Listeners(ctx context.Context) ([]kong.ProxyListener, []kong.StreamListener, error) { - return c.kongConfig.Client.Listeners(ctx) +// allEqual returns true if all provided objects are equal. +func allEqual[T any](objs ...T) bool { + l := len(objs) + if l == 0 || l == 1 { + return true + } + + obj := objs[0] + for i := 1; i < l; i++ { + if !reflect.DeepEqual(obj, objs[i]) { + return false + } + } + return true } -// RootWithTimeout provides the root configuration from Kong, but uses a configurable timeout to avoid long waits if the Admin API -// is not yet ready to respond. If a timeout error occurs, the caller is responsible for providing a retry mechanism. -func (c *KongClient) RootWithTimeout(ctx context.Context) (map[string]interface{}, error) { - ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) - defer cancel() - return c.kongConfig.Client.Root(ctx) +// Listeners retrieves the currently configured listeners from the underlying +// proxy so that callers can gather this metadata to know which ports +// and protocols are in use by the proxy. +func (c *KongClient) Listeners(ctx context.Context) ([]kong.ProxyListener, []kong.StreamListener, error) { + var ( + errg errgroup.Group + errgCollect errgroup.Group + listenersCh = make(chan []kong.ProxyListener) + listeners = make([][]kong.ProxyListener, 0) + streamListenersCh = make(chan []kong.StreamListener) + streamListeners = make([][]kong.StreamListener, 0) + ) + + errgCollect.Go(func() error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case l, ok := <-listenersCh: + if !ok { + return nil + } + listeners = append(listeners, l) + } + } + }) + errgCollect.Go(func() error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case sl, ok := <-streamListenersCh: + if !ok { + return nil + } + streamListeners = append(streamListeners, sl) + } + } + }) + + for _, cl := range c.kongConfig.Clients { + cl := cl + errg.Go(func() error { + listeners, streamListeners, err := cl.Listeners(ctx) + if err != nil { + return fmt.Errorf("failed to get listeners on %s: %w", cl.BaseRootURL(), err) + } + listenersCh <- listeners + streamListenersCh <- streamListeners + + return nil + }) + } + if err := errg.Wait(); err != nil { + return nil, nil, err + } + close(listenersCh) + close(streamListenersCh) + if err := errgCollect.Wait(); err != nil { + return nil, nil, err + } + + if !allEqual(listeners...) { + return nil, nil, fmt.Errorf("not all listeners out of %d are the same", len(listeners)) + } + + if !allEqual(streamListeners...) { + return nil, nil, fmt.Errorf("not all stream listeners out of %d are the same", len(streamListeners)) + } + + var ( + retListeners []kong.ProxyListener + retStreamListeners []kong.StreamListener + ) + if len(listeners) > 0 { + retListeners = listeners[0] + } + if len(streamListeners) > 0 { + retStreamListeners = streamListeners[0] + } + + return retListeners, retStreamListeners, nil } // ----------------------------------------------------------------------------- @@ -325,13 +379,14 @@ func (c *KongClient) Update(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to create parser: %w", err) } - formatVersion := "1.1" + if c.AreKubernetesObjectReportsEnabled() { p.EnableKubernetesObjectReports() } if c.AreCombinedServiceRoutesEnabled() { p.EnableCombinedServiceRoutes() } + formatVersion := "1.1" if versions.GetKongVersion().MajorMinorOnly().GTE(versions.ExplicitRegexPathVersionCutoff) { p.EnableRegexPathPrefix() formatVersion = "3.0" @@ -352,12 +407,80 @@ func (c *KongClient) Update(ctx context.Context) error { c.logger.Debug("successfully built data-plane configuration") } + shas, err := c.sendOutToClients(ctx, kongstate, formatVersion, c.kongConfig.FilterTags) + if err != nil { + return err + } + + // report on configured Kubernetes objects if enabled + if c.AreKubernetesObjectReportsEnabled() { + // if the configuration SHAs that have just been pushed are different than + // what's been previously pushed. + if !slices.Equal(shas, c.SHAs) { + report := p.GenerateKubernetesObjectReport() + c.logger.Debugf("triggering report for %d configured Kubernetes objects", len(report)) + c.triggerKubernetesObjectReport(report, translationFailures) + } else { + c.logger.Debug("no configuration change, skipping kubernetes object report") + } + } + return nil +} + +// sendOutToClients will generate deck content (config) from the provided kong state +// and send it out to each of the configured clients. +func (c *KongClient) sendOutToClients( + ctx context.Context, s *kongstate.KongState, formatVersion string, filterTags []string, +) ([]string, error) { + shas, err := iter.MapErr(c.kongConfig.Clients, func(client *sendconfig.ClientWithPluginStore) (string, error) { + return c.sendToClient(ctx, client, s, formatVersion, filterTags) + }, + ) + if err != nil { + return nil, err + } + previousSHAs := c.SHAs + + sort.Strings(shas) + c.SHAs = shas + + return previousSHAs, nil +} + +func (c *KongClient) sendToClient( + ctx context.Context, + client *sendconfig.ClientWithPluginStore, + s *kongstate.KongState, + formatVersion string, + filterTags []string, +) (string, error) { + var ( + logger = c.logger.WithField("kong_url", client.BaseRootURL()) + sendDiagnostic = func( + log logrus.FieldLogger, failed bool, ch chan<- util.ConfigDump, diagnosticConfig *file.Content, + ) { + // Given that we can send multiple configs to this channel and + // the fact that the API that exposes that can only expose 1 config + // at a time it means that users utilizing the diagnostics API + // might not see exactly what they indend to see i.e. come failures + // or successfully send configs might be covered by those send + // later on but we're OK with this limitation of said API. + select { + case ch <- util.ConfigDump{Failed: failed, Config: *diagnosticConfig}: + log.Debug("shipping config to diagnostic server") + default: + log.Error("config diagnostic buffer full, dropping diagnostic config") + } + } + ) + // generate the deck configuration to be applied to the admin API - c.logger.Debug("converting configuration to deck config") + logger.Debug("converting configuration to deck config") targetConfig := deckgen.ToDeckContent(ctx, - c.logger, kongstate, - c.kongConfig.PluginSchemaStore, - c.kongConfig.FilterTags, + logger, + s, + client.PluginSchemaStore, + filterTags, formatVersion, ) @@ -367,10 +490,10 @@ func (c *KongClient) Update(ctx context.Context) error { if c.diagnostic != (util.ConfigDumpDiagnostic{}) { if !c.diagnostic.DumpsIncludeSensitive { redactedConfig := deckgen.ToDeckContent(ctx, - c.logger, - kongstate.SanitizedCopy(), - c.kongConfig.PluginSchemaStore, - c.kongConfig.FilterTags, + logger, + s.SanitizedCopy(), + client.PluginSchemaStore, + filterTags, formatVersion, ) diagnosticConfig = redactedConfig @@ -380,60 +503,40 @@ func (c *KongClient) Update(ctx context.Context) error { } // apply the configuration update in Kong - c.logger.Debug("sending configuration to Kong Admin API") timedCtx, cancel := context.WithTimeout(ctx, c.requestTimeout) defer cancel() - newConfigSHA, err := sendconfig.PerformUpdate(timedCtx, - c.logger, - &c.kongConfig, + newConfigSHA, err := sendconfig.PerformUpdate( + timedCtx, + logger, + client.Client, + c.kongConfig.Version, + c.kongConfig.Concurrency, c.kongConfig.InMemory, c.enableReverseSync, c.skipCACertificates, targetConfig, - c.kongConfig.FilterTags, - c.lastConfigSHA, + filterTags, + client.LastConfigSHA(), c.prometheusMetrics, ) if err != nil { if expired, ok := timedCtx.Deadline(); ok && time.Now().After(expired) { - c.logger.Warn("exceeded Kong API timeout, consider increasing --proxy-timeout-seconds") + logger.Warn("exceeded Kong API timeout, consider increasing --proxy-timeout-seconds") } - // ship diagnostics if enabled if c.diagnostic != (util.ConfigDumpDiagnostic{}) { - select { - case c.diagnostic.Configs <- util.ConfigDump{Failed: true, Config: *diagnosticConfig}: - c.logger.Debug("shipping config to diagnostic server") - default: - c.logger.Error("config diagnostic buffer full, dropping diagnostic config") - } + sendDiagnostic(logger, true, c.diagnostic.Configs, diagnosticConfig) } - return err + return "", fmt.Errorf("performing update for %s failed: %w", client.BaseRootURL(), err) } - // ship diagnostics if enabled if c.diagnostic != (util.ConfigDumpDiagnostic{}) { - select { - case c.diagnostic.Configs <- util.ConfigDump{Failed: false, Config: *diagnosticConfig}: - c.logger.Debug("shipping config to diagnostic server") - default: - c.logger.Error("config diagnostic buffer full, dropping diagnostic config") - } - } - - // report on configured Kubernetes objects if enabled - if c.AreKubernetesObjectReportsEnabled() { - if string(c.lastConfigSHA) != string(newConfigSHA) { - report := p.GenerateKubernetesObjectReport() - c.logger.Debugf("triggering report for %d configured Kubernetes objects", len(report)) - c.triggerKubernetesObjectReport(report, translationFailures) - } else { - c.logger.Debug("no configuration change, skipping kubernetes object report") - } + sendDiagnostic(logger, false, c.diagnostic.Configs, diagnosticConfig) } // update the lastConfigSHA with the new updated checksum - c.lastConfigSHA = newConfigSHA - return nil + client.SetLastConfigSHA(newConfigSHA) + + return string(newConfigSHA), nil } // ----------------------------------------------------------------------------- diff --git a/internal/dataplane/sendconfig/kong.go b/internal/dataplane/sendconfig/kong.go index a3c0f33fdf..2adc536832 100644 --- a/internal/dataplane/sendconfig/kong.go +++ b/internal/dataplane/sendconfig/kong.go @@ -1,8 +1,14 @@ package sendconfig import ( + "context" + "fmt" + "github.com/blang/semver/v4" + "github.com/go-logr/logr" "github.com/kong/go-kong/kong" + "github.com/samber/lo" + "golang.org/x/sync/errgroup" "github.com/kong/kubernetes-ingress-controller/v2/internal/util" ) @@ -13,14 +19,78 @@ import ( // Kong Represents a Kong client and connection information. type Kong struct { - URL string - // If the gateway instance does not support tags, pass an empty FilterTags slice instead. - FilterTags []string - // Headers are injected into every request to Kong's Admin API - // to help with authorization/authentication. - Client *kong.Client - PluginSchemaStore *util.PluginSchemaStore - InMemory bool - Version semver.Version - Concurrency int + Clients []ClientWithPluginStore + + // Currently, this assumes that all underlying clients are using the same version + // hence this shared field in here. + Version semver.Version + InMemory bool + + Concurrency int + FilterTags []string +} + +// New creates new Kong client that is responsible for sending configurations +// to Kong instance(s) through Admin API. +func New( + ctx context.Context, + logger logr.Logger, + kongClients []*kong.Client, + v semver.Version, + dbMode string, + concurrency int, + filterTags []string, +) Kong { + var ( + errg errgroup.Group + tags []string + ) + + for _, cl := range kongClients { + cl := cl + errg.Go(func() error { + ok, err := cl.Tags.Exists(ctx) + if err != nil { + return fmt.Errorf("Kong Admin API (%s) does not support tags: %w", cl.BaseRootURL(), err) + } + if !ok { + return fmt.Errorf("Kong Admin API (%s) does not support tags", cl.BaseRootURL()) + } + return nil + }) + } + if err := errg.Wait(); err != nil { + logger.Error(err, "tag filtering disabled") + } else { + logger.Info("tag filtering enabled", "tags", filterTags) + tags = filterTags + } + + return Kong{ + InMemory: (dbMode == "off") || (dbMode == ""), + Version: v, + FilterTags: tags, + Concurrency: concurrency, + Clients: lo.Map(kongClients, func(client *kong.Client, index int) ClientWithPluginStore { + return ClientWithPluginStore{ + Client: client, + PluginSchemaStore: util.NewPluginSchemaStore(client), + } + }), + } +} + +type ClientWithPluginStore struct { + *kong.Client + *util.PluginSchemaStore + // lastConfigSHA is a checksum of the last successful update to the data-plane + lastConfigSHA []byte +} + +func (c *ClientWithPluginStore) SetLastConfigSHA(s []byte) { + c.lastConfigSHA = s +} + +func (c *ClientWithPluginStore) LastConfigSHA() []byte { + return c.lastConfigSHA } diff --git a/internal/dataplane/sendconfig/sendconfig.go b/internal/dataplane/sendconfig/sendconfig.go index 971fceb18c..5ebdfe7321 100644 --- a/internal/dataplane/sendconfig/sendconfig.go +++ b/internal/dataplane/sendconfig/sendconfig.go @@ -9,10 +9,10 @@ import ( "fmt" "net" "net/http" - "reflect" "sync" "time" + "github.com/blang/semver/v4" "github.com/kong/deck/diff" "github.com/kong/deck/dump" "github.com/kong/deck/file" @@ -35,7 +35,9 @@ const initialHash = "00000000000000000000000000000000" // PerformUpdate writes `targetContent` to Kong Admin API specified by `kongConfig`. func PerformUpdate(ctx context.Context, log logrus.FieldLogger, - kongConfig *Kong, + client *kong.Client, + version semver.Version, + concurrency int, inMemory bool, reverseSync bool, skipCACertificates bool, @@ -48,29 +50,33 @@ func PerformUpdate(ctx context.Context, if err != nil { return oldSHA, err } + // disable optimization if reverse sync is enabled if !reverseSync { // use the previous SHA to determine whether or not to perform an update - if equalSHA(oldSHA, newSHA) { + if bytes.Equal(oldSHA, newSHA) { if !hasSHAUpdateAlreadyBeenReported(newSHA) { log.Debugf("sha %s has been reported", hex.EncodeToString(newSHA)) } - // we assume ready as not all Kong versions provide their configuration hash, and their readiness state - // is always unknown + + // we assume ready as not all Kong versions provide their configuration hash, + // and their readiness state is always unknown ready := true - status, err := kongConfig.Client.Status(ctx) + + status, err := client.Status(ctx) if err != nil { - log.WithError(err).Error("checking config status failed") - log.Debug("configuration state unknown, skipping sync to kong") - return oldSHA, nil + return nil, err } + if status.ConfigurationHash == initialHash { ready = false } + if ready { log.Debug("no configuration change, skipping sync to kong") return oldSHA, nil } + log.Debugf("starting to send configuration (hash: %s)", status.ConfigurationHash) } } @@ -78,10 +84,11 @@ func PerformUpdate(ctx context.Context, timeStart := time.Now() if inMemory { metricsProtocol = metrics.ProtocolDBLess - err = onUpdateInMemoryMode(ctx, log, targetContent, kongConfig) + err = onUpdateInMemoryMode(ctx, log, targetContent, client) } else { metricsProtocol = metrics.ProtocolDeck - err = onUpdateDBMode(ctx, targetContent, kongConfig, selectorTags, skipCACertificates) + dumpConfig := dump.Config{SelectorTags: selectorTags, SkipCACerts: skipCACertificates} + err = onUpdateDBMode(ctx, targetContent, client, dumpConfig, version, concurrency) } timeEnd := time.Now() @@ -115,10 +122,11 @@ func PerformUpdate(ctx context.Context, // Sendconfig - Private Functions // ----------------------------------------------------------------------------- -func onUpdateInMemoryMode(ctx context.Context, +func onUpdateInMemoryMode( + ctx context.Context, log logrus.FieldLogger, state *file.Content, - kongConfig *Kong, + client *kong.Client, ) error { // Kong will error out if this is set state.Info = nil @@ -130,40 +138,29 @@ func onUpdateInMemoryMode(ctx context.Context, return fmt.Errorf("constructing kong configuration: %w", err) } - req, err := http.NewRequest("POST", kongConfig.URL+"/config", - bytes.NewReader(config)) - if err != nil { - return fmt.Errorf("creating new HTTP request for /config: %w", err) - } - req.Header.Add("content-type", "application/json") - - queryString := req.URL.Query() - queryString.Add("check_hash", "1") - - req.URL.RawQuery = queryString.Encode() - - _, err = kongConfig.Client.Do(ctx, req, nil) - if err != nil { - return fmt.Errorf("posting new config to /config: %w", err) + log.WithField("kong_url", client.BaseRootURL()). + Debug("sending configuration to Kong Admin API") + if err = client.Configs.ReloadDeclarativeRawConfig(ctx, bytes.NewReader(config), true); err != nil { + return err } - return err + return nil } -func onUpdateDBMode(ctx context.Context, +func onUpdateDBMode( + ctx context.Context, targetContent *file.Content, - kongConfig *Kong, - selectorTags []string, - skipCACertificates bool, + client *kong.Client, + dumpConfig dump.Config, + version semver.Version, + concurrency int, ) error { - dumpConfig := dump.Config{SelectorTags: selectorTags, SkipCACerts: skipCACertificates} - - cs, err := currentState(ctx, kongConfig, dumpConfig) + cs, err := currentState(ctx, client, dumpConfig) if err != nil { - return err + return fmt.Errorf("failed getting current state for %s: %w", client.BaseRootURL(), err) } - ts, err := targetState(ctx, targetContent, cs, kongConfig, dumpConfig) + ts, err := targetState(ctx, targetContent, cs, version, client, dumpConfig) if err != nil { return deckConfigConflictError{err} } @@ -171,22 +168,23 @@ func onUpdateDBMode(ctx context.Context, syncer, err := diff.NewSyncer(diff.SyncerOpts{ CurrentState: cs, TargetState: ts, - KongClient: kongConfig.Client, + KongClient: client, SilenceWarnings: true, }) if err != nil { - return fmt.Errorf("creating a new syncer: %w", err) + return fmt.Errorf("creating a new syncer for %s: %w", client.BaseRootURL(), err) } - _, errs := syncer.Solve(ctx, kongConfig.Concurrency, false) + _, errs := syncer.Solve(ctx, concurrency, false) if errs != nil { return deckutils.ErrArray{Errors: errs} } + return nil } -func currentState(ctx context.Context, kongConfig *Kong, dumpConfig dump.Config) (*state.KongState, error) { - rawState, err := dump.Get(ctx, kongConfig.Client, dumpConfig) +func currentState(ctx context.Context, kongClient *kong.Client, dumpConfig dump.Config) (*state.KongState, error) { + rawState, err := dump.Get(ctx, kongClient, dumpConfig) if err != nil { return nil, fmt.Errorf("loading configuration from kong: %w", err) } @@ -194,11 +192,18 @@ func currentState(ctx context.Context, kongConfig *Kong, dumpConfig dump.Config) return state.Get(rawState) } -func targetState(ctx context.Context, targetContent *file.Content, currentState *state.KongState, kongConfig *Kong, dumpConfig dump.Config) (*state.KongState, error) { +func targetState( + ctx context.Context, + targetContent *file.Content, + currentState *state.KongState, + version semver.Version, + kongClient *kong.Client, + dumpConfig dump.Config, +) (*state.KongState, error) { rawState, err := file.Get(ctx, targetContent, file.RenderConfig{ CurrentState: currentState, - KongVersion: kongConfig.Version, - }, dumpConfig, kongConfig.Client) + KongVersion: version, + }, dumpConfig, kongClient) if err != nil { return nil, err } @@ -206,10 +211,6 @@ func targetState(ctx context.Context, targetContent *file.Content, currentState return state.Get(rawState) } -func equalSHA(a, b []byte) bool { - return reflect.DeepEqual(a, b) -} - var ( latestReportedSHA []byte shaLock sync.RWMutex @@ -223,14 +224,13 @@ var ( // decisions (such as staggering or stifling duplicate log lines). // // TODO: This is a bit of a hack for now to keep backwards compat, -// -// but in the future we might configure rolling this into -// some object/interface which has this functionality as an -// inherent behavior. +// but in the future we might configure rolling this into +// some object/interface which has this functionality as an +// inherent behavior. func hasSHAUpdateAlreadyBeenReported(latestUpdateSHA []byte) bool { shaLock.Lock() defer shaLock.Unlock() - if equalSHA(latestReportedSHA, latestUpdateSHA) { + if bytes.Equal(latestReportedSHA, latestUpdateSHA) { return true } latestReportedSHA = latestUpdateSHA diff --git a/internal/dataplane/synchronizer.go b/internal/dataplane/synchronizer.go index b8a672ac70..fca4013fbb 100644 --- a/internal/dataplane/synchronizer.go +++ b/internal/dataplane/synchronizer.go @@ -88,6 +88,8 @@ func NewSynchronizer(logger logrus.FieldLogger, client Client, opts ...Synchroni opt(synchronizer) } + synchronizer.dbMode = client.DBMode() + return synchronizer, nil } @@ -182,7 +184,7 @@ func (p *Synchronizer) startUpdateServer(ctx context.Context) { case <-p.syncTicker.C: if err := p.dataplaneClient.Update(ctx); err != nil { p.logger.Error(err, "could not update kong admin") - break + continue } initialConfig.Do(p.markConfigApplied) } diff --git a/internal/manager/config.go b/internal/manager/config.go index dacb3380a3..3721349e75 100644 --- a/internal/manager/config.go +++ b/internal/manager/config.go @@ -50,7 +50,7 @@ type Config struct { APIServerBurst int MetricsAddr string ProbeAddr string - KongAdminURL string + KongAdminURL []string ProxySyncSeconds float32 ProxyTimeoutSeconds float32 @@ -144,7 +144,9 @@ func (c *Config) FlagSet() *pflag.FlagSet { flagSet.IntVar(&c.APIServerBurst, "apiserver-burst", 300, "The Kubernetes API RateLimiter maximum burst queries per second") flagSet.StringVar(&c.MetricsAddr, "metrics-bind-address", fmt.Sprintf(":%v", MetricsPort), "The address the metric endpoint binds to.") flagSet.StringVar(&c.ProbeAddr, "health-probe-bind-address", fmt.Sprintf(":%v", HealthzPort), "The address the probe endpoint binds to.") - flagSet.StringVar(&c.KongAdminURL, "kong-admin-url", "http://localhost:8001", `The Kong Admin URL to connect to in the format "protocol://address:port".`) + flagSet.StringSliceVar(&c.KongAdminURL, "kong-admin-url", []string{"http://localhost:8001"}, + `Kong Admin URL(s) to connect to in the format "protocol://address:port". `+ + `More than 1 URL can be provided, in such case the flag should be used multiple times or a corresponding env variable should use comma delimited addresses.`) flagSet.Float32Var(&c.ProxySyncSeconds, "proxy-sync-seconds", dataplane.DefaultSyncSeconds, "Define the rate (in seconds) in which configuration updates will be applied to the Kong Admin API.", ) @@ -234,16 +236,25 @@ func (c *Config) FlagSet() *pflag.FlagSet { return flagSet } -func (c *Config) GetKongClient(ctx context.Context) (*kong.Client, error) { - if c.KongAdminToken != "" { - c.KongAdminAPIConfig.Headers = append(c.KongAdminAPIConfig.Headers, "kong-admin-token:"+c.KongAdminToken) - } - httpclient, err := adminapi.MakeHTTPClient(&c.KongAdminAPIConfig) +// getKongClients returns the kong clients given the provided urls, workspace name +// and adminAPIConfig. +func getKongClients( + ctx context.Context, urls []string, workspace string, adminAPIConfig adminapi.HTTPClientOpts, +) ([]*kong.Client, error) { + httpclient, err := adminapi.MakeHTTPClient(&adminAPIConfig) if err != nil { return nil, err } - return adminapi.GetKongClientForWorkspace(ctx, c.KongAdminURL, c.KongWorkspace, httpclient) + clients := make([]*kong.Client, 0, len(urls)) + for _, url := range urls { + client, err := adminapi.GetKongClientForWorkspace(ctx, url, workspace, httpclient) + if err != nil { + return nil, err + } + clients = append(clients, client) + } + return clients, nil } func (c *Config) GetKubeconfig() (*rest.Config, error) { diff --git a/internal/manager/run.go b/internal/manager/run.go index f011d4c570..f85acefc95 100644 --- a/internal/manager/run.go +++ b/internal/manager/run.go @@ -9,9 +9,7 @@ import ( "regexp" "time" - "github.com/avast/retry-go/v4" "github.com/blang/semver/v4" - "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -24,8 +22,10 @@ import ( "github.com/kong/kubernetes-ingress-controller/v2/internal/controllers/gateway" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane" + "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/sendconfig" "github.com/kong/kubernetes-ingress-controller/v2/internal/manager/metadata" mgrutils "github.com/kong/kubernetes-ingress-controller/v2/internal/manager/utils" + "github.com/kong/kubernetes-ingress-controller/v2/internal/manager/utils/kongconfig" "github.com/kong/kubernetes-ingress-controller/v2/internal/util" "github.com/kong/kubernetes-ingress-controller/v2/internal/util/kubernetes/object/status" "github.com/kong/kubernetes-ingress-controller/v2/internal/versions" @@ -70,59 +70,30 @@ func Run(ctx context.Context, c *Config, diagnostic util.ConfigDumpDiagnostic, d } setupLog.Info("getting the kong admin api client configuration") - adminClient, err := c.GetKongClient(ctx) - if err != nil { - return fmt.Errorf("unable to build kong api client: %w", err) - } - - var kongRoot map[string]interface{} - err = retry.Do( - func() error { - kongRoot, err = adminClient.Root(ctx) - // Abort if the provided context has been cancelled. - if errors.Is(err, context.Canceled) { - return retry.Unrecoverable(err) - } - return err - }, - retry.Attempts(c.KongAdminInitializationRetries), - retry.Delay(c.KongAdminInitializationRetryDelay), - retry.DelayType(retry.FixedDelay), - retry.LastErrorOnly(true), - retry.OnRetry(func(n uint, err error) { - setupLog.Info("Retrying kong admin api client call after error", - "retries", fmt.Sprintf("%d/%d", n, c.KongAdminInitializationRetries), - "error", err.Error(), - ) - }), - ) - + if c.KongAdminToken != "" { + c.KongAdminAPIConfig.Headers = append(c.KongAdminAPIConfig.Headers, "kong-admin-token:"+c.KongAdminToken) + } + kongClients, err := getKongClients(ctx, c.KongAdminURL, c.KongWorkspace, c.KongAdminAPIConfig) if err != nil { - return fmt.Errorf("could not retrieve Kong admin root: %w", err) + return fmt.Errorf("unable to build kong api client(s): %w", err) } - kongConfig := setupKongConfig(ctx, adminClient, setupLog, c) - kongVersion, err := kong.ParseSemanticVersion(kong.VersionFromInfo(kongRoot)) + // Get Kong configuration root(s) to validate them and extract Kong's version. + kongRoots, err := kongconfig.GetRoots(ctx, setupLog, c.KongAdminInitializationRetries, c.KongAdminInitializationRetryDelay, kongClients) if err != nil { - setupLog.V(util.WarnLevel).Info("could not parse Kong version, version-specific behavior disabled", "error", err) - } else { - versions.SetKongVersion(semver.Version{Major: kongVersion.Major(), Minor: kongVersion.Minor(), Patch: kongVersion.Patch()}) - } - kongRootConfig, ok := kongRoot["configuration"].(map[string]interface{}) - if !ok { - return fmt.Errorf("invalid root configuration, expected a map[string]interface{} got %T", - kongRoot["configuration"]) + return fmt.Errorf("could not retrieve Kong admin root(s): %w", err) } - dbmode, ok := kongRootConfig["database"].(string) - if !ok { - return fmt.Errorf("invalid database configuration, expected a string got %T", kongRootConfig["database"]) - } - if dbmode == "off" && c.SkipCACertificates { - return fmt.Errorf("--skip-ca-certificates is not available for use with DB-less Kong instances") + dbMode, v, err := kongconfig.ValidateRoots(kongRoots, c.SkipCACertificates) + if err != nil { + return fmt.Errorf("could not validate Kong admin root(s) configuration: %w", err) } + semV := semver.Version{Major: v.Major(), Minor: v.Minor(), Patch: v.Patch()} + versions.SetKongVersion(semV) + kongConfig := sendconfig.New(ctx, setupLog, kongClients, semV, dbMode, c.Concurrency, c.FilterTags) + setupLog.Info("configuring and building the controller manager") - controllerOpts, err := setupControllerOptions(setupLog, c, scheme, dbmode) + controllerOpts, err := setupControllerOptions(setupLog, c, scheme, dbMode) if err != nil { return fmt.Errorf("unable to setup controller options: %w", err) } @@ -137,22 +108,18 @@ func Run(ctx context.Context, c *Config, diagnostic util.ConfigDumpDiagnostic, d } setupLog.Info("Initializing Dataplane Client") - timeoutDuration, err := time.ParseDuration(fmt.Sprintf("%gs", c.ProxyTimeoutSeconds)) - if err != nil { - return fmt.Errorf("%f is not a valid number of seconds to the timeout config for the kong client: %w", c.ProxyTimeoutSeconds, err) - } - eventRecorder := mgr.GetEventRecorderFor(KongClientEventRecorderComponentName) dataplaneClient, err := dataplane.NewKongClient( ctx, deprecatedLogger, - timeoutDuration, + time.Duration(c.ProxyTimeoutSeconds*float32(time.Second)), c.IngressClassName, c.EnableReverseSync, c.SkipCACertificates, diagnostic, kongConfig, eventRecorder, + dbMode, ) if err != nil { return fmt.Errorf("failed to initialize kong data-plane client: %w", err) diff --git a/internal/manager/setup.go b/internal/manager/setup.go index d40690789f..55a1dec2ff 100644 --- a/internal/manager/setup.go +++ b/internal/manager/setup.go @@ -10,7 +10,6 @@ import ( "github.com/bombsimon/logrusr/v2" "github.com/go-logr/logr" "github.com/kong/deck/cprint" - "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -22,7 +21,6 @@ import ( "github.com/kong/kubernetes-ingress-controller/v2/internal/admission" "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane" - "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/sendconfig" "github.com/kong/kubernetes-ingress-controller/v2/internal/util" ) @@ -114,24 +112,6 @@ func setupControllerOptions(logger logr.Logger, c *Config, scheme *runtime.Schem return controllerOpts, nil } -func setupKongConfig(ctx context.Context, kongClient *kong.Client, logger logr.Logger, c *Config) sendconfig.Kong { - var filterTags []string - if ok, err := kongClient.Tags.Exists(ctx); err != nil { - logger.Error(err, "tag filtering disabled because Kong Admin API does not support tags") - } else if ok { - logger.Info("tag filtering enabled", "tags", c.FilterTags) - filterTags = c.FilterTags - } - - return sendconfig.Kong{ - URL: c.KongAdminURL, - FilterTags: filterTags, - Concurrency: c.Concurrency, - Client: kongClient, - PluginSchemaStore: util.NewPluginSchemaStore(kongClient), - } -} - func setupDataplaneSynchronizer( logger logr.Logger, fieldLogger logrus.FieldLogger, @@ -176,14 +156,26 @@ func setupAdmissionServer( return nil } - kongclient, err := managerConfig.GetKongClient(ctx) + kongclients, err := getKongClients(ctx, + managerConfig.KongAdminURL, + managerConfig.KongWorkspace, + managerConfig.KongAdminAPIConfig, + ) if err != nil { return err } srv, err := admission.MakeTLSServer(ctx, &managerConfig.AdmissionServer, &admission.RequestHandler{ Validator: admission.NewKongHTTPValidator( - kongclient.Consumers, - kongclient.Plugins, + // For now using first client is kind of OK. Using Consumer and Plugin + // services from first kong client should theoretically return the same + // results as for all other clients. There might be instances where + // configurations in different Kong Gateways are ever so slightly + // different but that shouldn't cause a fatal failure. + // + // TODO: We should take a look at this sooner rather than later. + // https://github.com/Kong/kubernetes-ingress-controller/issues/3363 + kongclients[0].Consumers, + kongclients[0].Plugins, logger, managerClient, managerConfig.IngressClassName, diff --git a/internal/manager/utils/kongconfig/root.go b/internal/manager/utils/kongconfig/root.go new file mode 100644 index 0000000000..aabdf25bd2 --- /dev/null +++ b/internal/manager/utils/kongconfig/root.go @@ -0,0 +1,198 @@ +package kongconfig + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/avast/retry-go/v4" + "github.com/go-logr/logr" + "github.com/kong/go-kong/kong" + "github.com/samber/lo" + "go.uber.org/multierr" + "golang.org/x/sync/errgroup" +) + +// ValidateRoots checks if all provided kong roots are the same given that we +// only care about the fact that the following fields are the same: +// - database setting +// - kong version. +func ValidateRoots(roots []Root, skipCACerts bool) (string, kong.Version, error) { + if err := multierr.Combine(lo.Map(roots, validateRootFunc(skipCACerts))...); err != nil { + return "", kong.Version{}, fmt.Errorf("failed to validate kong Roots: %w", err) + } + + uniqs := lo.UniqBy(roots, getRootKeyFunc(skipCACerts)) + if len(uniqs) > 1 { + return "", kong.Version{}, + fmt.Errorf("there should only be one dbmode:version combination across configured kong instances while there are: %v", uniqs) + } + + dbMode, err := DBModeFromRoot(uniqs[0]) + if err != nil { + return "", kong.Version{}, err + } + + kongVersion, err := KongVersionFromRoot(uniqs[0]) + if err != nil { + return "", kong.Version{}, err + } + + return dbMode, kongVersion, nil +} + +func DBModeFromRoot(r Root) (string, error) { + rootConfig, ok := r["configuration"].(map[string]any) + if !ok { + return "", fmt.Errorf( + "invalid root configuration, expected a map[string]any got %T", + r["configuration"], + ) + } + + dbMode, ok := rootConfig["database"].(string) + if !ok { + return "", fmt.Errorf( + "invalid database configuration, expected a string got %t", + rootConfig["database"], + ) + } + return dbMode, nil +} + +func KongVersionFromRoot(r Root) (kong.Version, error) { + v := kong.VersionFromInfo(r) + kv, err := kong.ParseSemanticVersion(v) + if err != nil { + return kong.Version{}, fmt.Errorf("could not parse Kong version (%s): %w", v, err) + } + return kv, nil +} + +// Root represents Kong Gateway configuration root. +type Root map[string]any + +func (kr Root) Validate(skipCACerts bool) error { + dbMode, err := DBModeFromRoot(kr) + if err != nil { + return err + } + + if err := validateDBMode(dbMode, skipCACerts); err != nil { + return err + } + + if _, err = KongVersionFromRoot(kr); err != nil { + return err + } + + return nil +} + +func (kr Root) Key(skipCACerts bool) string { + dbMode, err := DBModeFromRoot(kr) + if err != nil { + return "" + } + + if err := validateDBMode(dbMode, skipCACerts); err != nil { + return "" + } + + v := kong.VersionFromInfo(kr) + _, err = kong.ParseSemanticVersion(v) + if err != nil { + return "" + } + + return fmt.Sprintf("%s:%s", dbMode, v) +} + +func validateRootFunc(skipCACerts bool) func(Root, int) error { + return func(r Root, _ int) error { + return r.Validate(skipCACerts) + } +} + +// getRootKeyFunc generates a key for mapping a kong root to a string. +// It assumes that the provided configuration root has already been verified with a validation +// function return by validateRootFunc. +func getRootKeyFunc(skipCACerts bool) func(Root) string { + return func(r Root) string { + return r.Key(skipCACerts) + } +} + +// validateDBMode validates the provided dbMode string. +func validateDBMode(dbMode string, skipCACerts bool) error { + switch dbMode { + case "off", "": + if skipCACerts { + return fmt.Errorf("--skip-ca-certificates is not available for use with DB-less Kong instances") + } + case "postgres": + return nil + case "cassandra": + return fmt.Errorf("Cassandra-backed deployments of Kong managed by the ingress controller are no longer supported; you must migrate to a Postgres-backed or DB-less deployment") + default: + return fmt.Errorf("%s is not a supported database backend", dbMode) + } + return nil +} + +// GetRoots fetches all the configuration roots using the provided kong clients. +func GetRoots( + ctx context.Context, + setupLog logr.Logger, + retries uint, + retryDelay time.Duration, + kongClients []*kong.Client, +) ([]Root, error) { + var ( + roots []Root + lock sync.Mutex + ) + + eg, ctx := errgroup.WithContext(ctx) + + for _, client := range kongClients { + client := client + eg.Go(func() error { + return retry.Do( + func() error { + root, err := client.Root(ctx) + // Abort if the provided context has been cancelled. + if errors.Is(err, context.Canceled) { + return retry.Unrecoverable(err) + } + if err != nil { + return err + } + + lock.Lock() + roots = append(roots, root) + lock.Unlock() + return nil + }, + retry.Attempts(retries), + retry.Delay(retryDelay), + retry.DelayType(retry.FixedDelay), + retry.LastErrorOnly(true), + retry.OnRetry(func(n uint, err error) { + setupLog.Info("Retrying kong admin api client call after error", + "retries", fmt.Sprintf("%d/%d", n, retries), + "error", err.Error(), + ) + }), + ) + }) + } + + if err := eg.Wait(); err != nil { + return nil, err + } + + return roots, nil +} diff --git a/internal/manager/utils/kongconfig/root_test.go b/internal/manager/utils/kongconfig/root_test.go new file mode 100644 index 0000000000..ae2a03e2f7 --- /dev/null +++ b/internal/manager/utils/kongconfig/root_test.go @@ -0,0 +1,661 @@ +package kongconfig + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRoot(t *testing.T) { + var root Root + require.NoError(t, json.Unmarshal([]byte(dblessConfigJSON), &root)) + require.NoError(t, root.Validate(false)) + require.EqualError(t, root.Validate(true), "--skip-ca-certificates is not available for use with DB-less Kong instances") +} + +func TestValidateRoots(t *testing.T) { + var root Root + require.NoError(t, json.Unmarshal([]byte(dblessConfigJSON), &root)) + dbmode, v, err := ValidateRoots([]Root{root, root}, false) + require.NoError(t, err) + assert.Equal(t, "off", dbmode) + assert.Equal(t, "3.1.1", v.String()) +} + +const dblessConfigJSON = `{ + "plugins": { + "enabled_in_cluster": [], + "available_on_server": { + "basic-auth": { + "version": "3.1.1", + "priority": 1100 + }, + "ip-restriction": { + "version": "3.1.1", + "priority": 990 + }, + "request-transformer": { + "version": "3.1.1", + "priority": 801 + }, + "response-transformer": { + "version": "3.1.1", + "priority": 800 + }, + "request-size-limiting": { + "version": "3.1.1", + "priority": 951 + }, + "rate-limiting": { + "version": "3.1.1", + "priority": 910 + }, + "response-ratelimiting": { + "version": "3.1.1", + "priority": 900 + }, + "syslog": { + "version": "3.1.1", + "priority": 4 + }, + "loggly": { + "version": "3.1.1", + "priority": 6 + }, + "datadog": { + "version": "3.1.1", + "priority": 10 + }, + "ldap-auth": { + "version": "3.1.1", + "priority": 1200 + }, + "statsd": { + "version": "3.1.1", + "priority": 11 + }, + "bot-detection": { + "version": "3.1.1", + "priority": 2500 + }, + "aws-lambda": { + "version": "3.1.1", + "priority": 750 + }, + "request-termination": { + "version": "3.1.1", + "priority": 2 + }, + "prometheus": { + "version": "3.1.1", + "priority": 13 + }, + "proxy-cache": { + "version": "3.1.1", + "priority": 100 + }, + "session": { + "version": "3.1.1", + "priority": 1900 + }, + "acme": { + "version": "3.1.1", + "priority": 1705 + }, + "grpc-gateway": { + "version": "3.1.1", + "priority": 998 + }, + "grpc-web": { + "version": "3.1.1", + "priority": 3 + }, + "pre-function": { + "version": "3.1.1", + "priority": 1000000 + }, + "post-function": { + "version": "3.1.1", + "priority": -1000 + }, + "azure-functions": { + "version": "3.1.1", + "priority": 749 + }, + "zipkin": { + "version": "3.1.1", + "priority": 100000 + }, + "opentelemetry": { + "version": "0.1.0", + "priority": 14 + }, + "jwt": { + "version": "3.1.1", + "priority": 1450 + }, + "acl": { + "version": "3.1.1", + "priority": 950 + }, + "correlation-id": { + "version": "3.1.1", + "priority": 1 + }, + "cors": { + "version": "3.1.1", + "priority": 2000 + }, + "oauth2": { + "version": "3.1.1", + "priority": 1400 + }, + "tcp-log": { + "version": "3.1.1", + "priority": 7 + }, + "udp-log": { + "version": "3.1.1", + "priority": 8 + }, + "file-log": { + "version": "3.1.1", + "priority": 9 + }, + "http-log": { + "version": "3.1.1", + "priority": 12 + }, + "key-auth": { + "version": "3.1.1", + "priority": 1250 + }, + "hmac-auth": { + "version": "3.1.1", + "priority": 1030 + } + } + }, + "tagline": "Welcome to kong", + "lua_version": "LuaJIT 2.1.0-20220411", + "version": "3.1.1", + "pids": { + "master": 1, + "workers": [ + 1133, + 1134 + ] + }, + "configuration": { + "nginx_http_client_body_buffer_size": "8k", + "proxy_ssl_enabled": true, + "cluster_listeners": {}, + "role": "traditional", + "vaults": [ + "bundled" + ], + "ssl_cert": [ + "/kong_prefix/ssl/kong-default.crt", + "/kong_prefix/ssl/kong-default-ecdsa.crt" + ], + "loaded_vaults": { + "env": true + }, + "real_ip_header": "X-Real-IP", + "nginx_proxy_real_ip_header": "X-Real-IP", + "real_ip_recursive": "off", + "nginx_proxy_real_ip_recursive": "off", + "pg_port": 5432, + "pg_ssl": false, + "pg_ssl_verify": false, + "pg_max_concurrent_queries": 0, + "pg_semaphore_timeout": 60000, + "log_level": "notice", + "pg_ro_ssl_verify": false, + "cassandra_contact_points": [ + "127.0.0.1" + ], + "cassandra_port": 9042, + "cassandra_ssl": false, + "cassandra_ssl_verify": false, + "cassandra_write_consistency": "ONE", + "cassandra_read_consistency": "ONE", + "cassandra_lb_policy": "RequestRoundRobin", + "cassandra_refresh_frequency": 60, + "cassandra_repl_strategy": "SimpleStrategy", + "prefix": "/kong_prefix", + "cassandra_repl_factor": 1, + "cassandra_data_centers": [ + "dc1:2", + "dc2:3" + ], + "status_ssl_enabled": false, + "ssl_protocols": "TLSv1.1 TLSv1.2 TLSv1.3", + "lua_ssl_trusted_certificate_combined": "/kong_prefix/.ca_combined", + "nginx_http_ssl_protocols": "TLSv1.2 TLSv1.3", + "nginx_stream_ssl_protocols": "TLSv1.2 TLSv1.3", + "ssl_prefer_server_ciphers": "on", + "nginx_http_ssl_prefer_server_ciphers": "off", + "nginx_stream_ssl_prefer_server_ciphers": "off", + "ssl_dhparam": "ffdhe2048", + "nginx_http_ssl_dhparam": "ffdhe2048", + "nginx_stream_ssl_dhparam": "ffdhe2048", + "ssl_session_tickets": "on", + "nginx_http_ssl_session_tickets": "on", + "nginx_stream_ssl_session_tickets": "on", + "ssl_session_timeout": "1d", + "nginx_http_ssl_session_timeout": "1d", + "nginx_stream_ssl_session_timeout": "1d", + "proxy_access_log": "/dev/stdout", + "proxy_error_log": "/dev/stderr", + "proxy_stream_access_log": "/dev/stdout basic", + "proxy_stream_error_log": "/dev/stderr", + "admin_access_log": "/dev/stdout", + "admin_error_log": "/dev/stderr", + "status_access_log": "off", + "status_error_log": "/dev/stderr", + "lua_ssl_trusted_certificate": [ + "/etc/ssl/certs/ca-certificates.crt" + ], + "lua_ssl_verify_depth": 1, + "lua_ssl_protocols": "TLSv1.1 TLSv1.2 TLSv1.3", + "nginx_http_lua_ssl_protocols": "TLSv1.1 TLSv1.2 TLSv1.3", + "nginx_stream_lua_ssl_protocols": "TLSv1.1 TLSv1.2 TLSv1.3", + "lua_socket_pool_size": 30, + "nginx_admin_client_max_body_size": "10m", + "cluster_mtls": "shared", + "nginx_http_lua_regex_match_limit": "100000", + "cassandra_timeout": 5000, + "pg_timeout": 5000, + "worker_state_update_frequency": 5, + "cluster_max_payload": 4194304, + "client_body_buffer_size": "8k", + "untrusted_lua": "sandbox", + "untrusted_lua_sandbox_requires": {}, + "untrusted_lua_sandbox_environment": {}, + "pg_host": "127.0.0.1", + "lmdb_map_size": "128m", + "proxy_server_ssl_verify": true, + "pg_database": "kong", + "nginx_events_directives": [ + { + "name": "multi_accept", + "value": "on" + }, + { + "name": "worker_connections", + "value": "auto" + } + ], + "nginx_http_directives": [ + { + "name": "client_body_buffer_size", + "value": "8k" + }, + { + "name": "client_max_body_size", + "value": "0" + }, + { + "name": "lua_regex_cache_max_entries", + "value": "8192" + }, + { + "name": "lua_regex_match_limit", + "value": "100000" + }, + { + "name": "lua_shared_dict", + "value": "prometheus_metrics 5m" + }, + { + "name": "lua_ssl_protocols", + "value": "TLSv1.1 TLSv1.2 TLSv1.3" + }, + { + "name": "ssl_dhparam", + "value": "/kong_prefix/ssl/ffdhe2048.pem" + }, + { + "name": "ssl_prefer_server_ciphers", + "value": "off" + }, + { + "name": "ssl_protocols", + "value": "TLSv1.2 TLSv1.3" + }, + { + "name": "ssl_session_tickets", + "value": "on" + }, + { + "name": "ssl_session_timeout", + "value": "1d" + } + ], + "pg_user": "kong", + "nginx_upstream_directives": {}, + "upstream_keepalive_idle_timeout": 60, + "upstream_keepalive_max_requests": 100, + "nginx_status_directives": {}, + "nginx_admin_directives": [ + { + "name": "client_body_buffer_size", + "value": "10m" + }, + { + "name": "client_max_body_size", + "value": "10m" + } + ], + "nginx_stream_directives": [ + { + "name": "lua_shared_dict", + "value": "stream_prometheus_metrics 5m" + }, + { + "name": "lua_ssl_protocols", + "value": "TLSv1.1 TLSv1.2 TLSv1.3" + }, + { + "name": "ssl_dhparam", + "value": "/kong_prefix/ssl/ffdhe2048.pem" + }, + { + "name": "ssl_prefer_server_ciphers", + "value": "off" + }, + { + "name": "ssl_protocols", + "value": "TLSv1.2 TLSv1.3" + }, + { + "name": "ssl_session_tickets", + "value": "on" + }, + { + "name": "ssl_session_timeout", + "value": "1d" + } + ], + "nginx_supstream_directives": {}, + "nginx_sproxy_directives": {}, + "opentelemetry_tracing": [ + "off" + ], + "nginx_pid": "/kong_prefix/pids/nginx.pid", + "kic": false, + "pluginserver_names": {}, + "nginx_err_logs": "/kong_prefix/logs/error.log", + "nginx_events_multi_accept": "on", + "pg_ro_ssl": false, + "cassandra_keyspace": "kong", + "nginx_events_worker_connections": "auto", + "declarative_config": "/kong_dbless/kong.yml", + "admin_ssl_cert": {}, + "nginx_conf": "/kong_prefix/nginx.conf", + "cassandra_username": "kong", + "nginx_kong_conf": "/kong_prefix/nginx-kong.conf", + "nginx_main_worker_rlimit_nofile": "auto", + "nginx_kong_stream_conf": "/kong_prefix/nginx-kong-stream.conf", + "plugins": [ + "bundled" + ], + "dns_hostsfile": "/etc/hosts", + "kong_process_secrets": "/kong_prefix/.kong_process_secrets", + "stream_listeners": {}, + "ssl_cert_csr_default": "/kong_prefix/ssl/kong-default.csr", + "error_default_type": "text/plain", + "ssl_cert_default": "/kong_prefix/ssl/kong-default.crt", + "dns_error_ttl": 1, + "ssl_cert_key_default": "/kong_prefix/ssl/kong-default.key", + "dns_not_found_ttl": 30, + "ssl_cert_default_ecdsa": "/kong_prefix/ssl/kong-default-ecdsa.crt", + "dns_stale_ttl": 4, + "mem_cache_size": "128m", + "dns_cache_size": 10000, + "client_ssl_cert_default": "/kong_prefix/ssl/kong-default.crt", + "dns_order": [ + "LAST", + "SRV", + "A", + "CNAME" + ], + "admin_ssl_cert_default": "/kong_prefix/ssl/admin-kong-default.crt", + "dns_no_sync": false, + "admin_ssl_cert_key_default": "/kong_prefix/ssl/admin-kong-default.key", + "client_ssl": false, + "enabled_headers": { + "Via": true, + "Server": true, + "X-Kong-Admin-Latency": true, + "X-Kong-Upstream-Latency": true, + "X-Kong-Upstream-Status": false, + "server_tokens": true, + "latency_tokens": true, + "X-Kong-Response-Latency": true, + "X-Kong-Proxy-Latency": true + }, + "dns_resolver": {}, + "admin_ssl_cert_key_default_ecdsa": "/kong_prefix/ssl/admin-kong-default-ecdsa.key", + "ssl_ciphers": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384", + "status_ssl_cert_default": "/kong_prefix/ssl/status-kong-default.crt", + "proxy_listen": [ + "0.0.0.0:8000", + "0.0.0.0:8443 http2 ssl" + ], + "status_ssl_cert_key_default": "/kong_prefix/ssl/status-kong-default.key", + "opentelemetry_tracing_sampling_rate": 1, + "status_ssl_cert_default_ecdsa": "/kong_prefix/ssl/status-kong-default-ecdsa.crt", + "stream_proxy_ssl_enabled": false, + "status_ssl_cert_key_default_ecdsa": "/kong_prefix/ssl/status-kong-default-ecdsa.key", + "loaded_plugins": { + "basic-auth": true, + "ip-restriction": true, + "request-transformer": true, + "response-transformer": true, + "request-size-limiting": true, + "rate-limiting": true, + "response-ratelimiting": true, + "syslog": true, + "loggly": true, + "datadog": true, + "ldap-auth": true, + "statsd": true, + "bot-detection": true, + "aws-lambda": true, + "request-termination": true, + "prometheus": true, + "proxy-cache": true, + "session": true, + "acme": true, + "grpc-gateway": true, + "grpc-web": true, + "pre-function": true, + "post-function": true, + "azure-functions": true, + "zipkin": true, + "opentelemetry": true, + "jwt": true, + "acl": true, + "correlation-id": true, + "cors": true, + "oauth2": true, + "tcp-log": true, + "udp-log": true, + "file-log": true, + "http-log": true, + "key-auth": true, + "hmac-auth": true + }, + "ssl_cert_key": [ + "/kong_prefix/ssl/kong-default.key", + "/kong_prefix/ssl/kong-default-ecdsa.key" + ], + "lua_package_cpath": "", + "port_maps": [ + "80:8000", + "443:8443" + ], + "lua_package_path": "/opt/?.lua;/opt/?/init.lua;;", + "admin_listen": [ + "0.0.0.0:8001" + ], + "status_listen": [ + "0.0.0.0:8100" + ], + "stream_listen": [ + "off" + ], + "cluster_listen": [ + "off" + ], + "db_cache_warmup_entities": [ + "services" + ], + "admin_ssl_cert_key": {}, + "status_ssl_cert": {}, + "status_ssl_cert_key": {}, + "db_resurrect_ttl": 30, + "nginx_user": "kong kong", + "headers": [ + "server_tokens", + "latency_tokens" + ], + "nginx_daemon": "off", + "cluster_ocsp": "off", + "nginx_main_daemon": "off", + "nginx_worker_processes": "2", + "nginx_main_worker_processes": "2", + "trusted_ips": {}, + "upstream_keepalive_pool_size": 60, + "anonymous_reports": true, + "host_ports": { + "8000": 80, + "8443": 443 + }, + "cluster_data_plane_purge_delay": 1209600, + "lmdb_environment_path": "dbless.lmdb", + "cluster_use_proxy": false, + "database": "off", + "router_flavor": "traditional", + "legacy_worker_events": false, + "cluster_control_plane": "127.0.0.1:8005", + "admin_listeners": [ + { + "backlog=%d+": false, + "ipv6only=on": false, + "ipv6only=off": false, + "ssl": false, + "so_keepalive=off": false, + "so_keepalive=%w*:%w*:%d*": false, + "listener": "0.0.0.0:8001", + "bind": false, + "port": 8001, + "deferred": false, + "so_keepalive=on": false, + "http2": false, + "proxy_protocol": false, + "ip": "0.0.0.0", + "reuseport": false + } + ], + "nginx_proxy_directives": [ + { + "name": "real_ip_header", + "value": "X-Real-IP" + }, + { + "name": "real_ip_recursive", + "value": "off" + } + ], + "nginx_admin_client_body_buffer_size": "10m", + "ssl_cert_key_default_ecdsa": "/kong_prefix/ssl/kong-default-ecdsa.key", + "nginx_main_user": "kong kong", + "nginx_main_directives": [ + { + "name": "daemon", + "value": "off" + }, + { + "name": "user", + "value": "kong kong" + }, + { + "name": "worker_processes", + "value": "2" + }, + { + "name": "worker_rlimit_nofile", + "value": "auto" + } + ], + "nginx_http_lua_regex_cache_max_entries": "8192", + "worker_consistency": "eventual", + "admin_ssl_enabled": false, + "admin_ssl_cert_default_ecdsa": "/kong_prefix/ssl/admin-kong-default-ecdsa.crt", + "nginx_acc_logs": "/kong_prefix/logs/access.log", + "status_listeners": [ + { + "port": 8100, + "ip": "0.0.0.0", + "listener": "0.0.0.0:8100", + "ssl": false + } + ], + "admin_acc_logs": "/kong_prefix/logs/admin_access.log", + "cassandra_schema_consensus_timeout": 10000, + "db_update_frequency": 5, + "proxy_listeners": [ + { + "backlog=%d+": false, + "ipv6only=on": false, + "ipv6only=off": false, + "ssl": false, + "so_keepalive=off": false, + "so_keepalive=%w*:%w*:%d*": false, + "listener": "0.0.0.0:8000", + "bind": false, + "port": 8000, + "deferred": false, + "so_keepalive=on": false, + "http2": false, + "proxy_protocol": false, + "ip": "0.0.0.0", + "reuseport": false + }, + { + "backlog=%d+": false, + "ipv6only=on": false, + "ipv6only=off": false, + "ssl": true, + "so_keepalive=off": false, + "so_keepalive=%w*:%w*:%d*": false, + "listener": "0.0.0.0:8443 ssl http2", + "bind": false, + "port": 8443, + "deferred": false, + "so_keepalive=on": false, + "http2": true, + "proxy_protocol": false, + "ip": "0.0.0.0", + "reuseport": false + } + ], + "db_update_propagation": 0, + "client_ssl_cert_key_default": "/kong_prefix/ssl/kong-default.key", + "db_cache_ttl": 0, + "kong_env": "/kong_prefix/.kong_env", + "nginx_http_client_max_body_size": "0", + "ssl_cipher_suite": "intermediate" + }, + "node_id": "10932f25-0601-4c18-a8e2-811c64995df2", + "timers": { + "running": 37, + "pending": 1 + }, + "hostname": "kong-kong-8d76d469d-zdjhb" +}` diff --git a/internal/manager/utils/reports.go b/internal/manager/utils/reports.go index 70c62fe9ee..f15b4c8b45 100644 --- a/internal/manager/utils/reports.go +++ b/internal/manager/utils/reports.go @@ -55,8 +55,17 @@ func RunReport( return fmt.Errorf("failed to get pod details: %w", err) } + // This now only uses the first instance for telemetry reporting. + // That's fine because we allow for now only 1 set of version and db setting + // throughout all Kong instances that 1 KIC instance configures. + // + // When we change that and decide to allow heterogenous Kong instances to be + // configured by 1 KIC instance then this will have to change. + // + // https://github.com/Kong/kubernetes-ingress-controller/issues/3362 + // gather versioning information from the kong client - root, err := kongCfg.Client.Root(ctx) + root, err := kongCfg.Clients[0].Root(ctx) if err != nil { return fmt.Errorf("failed to get Kong root config data: %w", err) } diff --git a/internal/util/plugin_schema_helper.go b/internal/util/plugin_schema_helper.go index e621eb37fb..9a45b11543 100644 --- a/internal/util/plugin_schema_helper.go +++ b/internal/util/plugin_schema_helper.go @@ -7,9 +7,6 @@ import ( "github.com/kong/go-kong/kong" ) -// FIXME -// decK will release this official API soon, use that and remove this code. - // PluginSchemaStore retrives a schema of a Plugin from Kong. type PluginSchemaStore struct { client *kong.Client