From 9b498196f908ef2ceb4b02b065818485e8efe19f Mon Sep 17 00:00:00 2001 From: derailed Date: Sun, 27 Jun 2021 23:22:13 -0600 Subject: [PATCH] fix #1163 #1153 #1151 #1140 #1137 #1132 #1131 --- .goreleaser.yml | 2 +- Makefile | 2 +- README.md | 12 +- change_logs/release_v0.24.10.md | 2 +- change_logs/release_v0.24.11.md | 31 ++++ cmd/root.go | 4 - go.sum | 240 ++++++++++++++++++++++++++++ internal/client/config.go | 2 +- internal/client/helpers.go | 5 + internal/config/alias.go | 22 ++- internal/config/helpers.go | 1 + internal/config/k9s.go | 1 + internal/config/styles.go | 2 +- internal/dao/container.go | 2 +- internal/dao/cronjob.go | 2 +- internal/dao/dp.go | 2 +- internal/dao/ds.go | 5 +- internal/dao/job.go | 2 +- internal/dao/log_item.go | 142 ++-------------- internal/dao/log_item_test.go | 128 +-------------- internal/dao/log_items.go | 215 +++++++++++++++++++++++++ internal/dao/log_items_test.go | 128 +++++++++++++++ internal/dao/log_options.go | 70 +++++--- internal/dao/log_options_test.go | 43 +++++ internal/dao/pod.go | 51 +++--- internal/dao/pod_test.go | 27 +++- internal/dao/screen_dump.go | 1 + internal/dao/sts.go | 18 ++- internal/dao/svc.go | 2 +- internal/dao/types.go | 2 +- internal/model/cluster_info.go | 4 +- internal/model/log.go | 108 ++++++------- internal/model/log_int_test.go | 4 +- internal/model/log_test.go | 62 +++---- internal/model/stack_test.go | 1 + internal/model/types.go | 5 + internal/render/table_data.go | 4 +- internal/ui/config.go | 9 +- internal/ui/crumbs_test.go | 1 + internal/ui/prompt.go | 2 +- internal/ui/table.go | 2 +- internal/ui/table_helper.go | 2 +- internal/view/actions.go | 5 +- internal/view/alias.go | 4 +- internal/view/app.go | 21 +-- internal/view/browser.go | 13 ++ internal/view/command.go | 3 + internal/view/container.go | 29 +++- internal/view/context.go | 2 +- internal/view/cow.go | 4 + internal/view/details.go | 4 + internal/view/dp.go | 67 ++++++-- internal/view/help.go | 31 ++-- internal/view/help_test.go | 2 +- internal/view/live_view.go | 4 + internal/view/log.go | 40 ++--- internal/view/log_dialog.go | 80 ---------- internal/view/log_indicator.go | 8 +- internal/view/log_indicator_test.go | 8 +- internal/view/log_int_test.go | 53 ++++-- internal/view/log_test.go | 55 ++++--- internal/view/logs_extender.go | 35 +++- internal/view/ns.go | 4 +- internal/view/picker.go | 4 + internal/view/pod.go | 69 ++++---- internal/view/pulse.go | 12 +- internal/view/reference.go | 5 +- internal/view/registrar.go | 8 +- internal/view/sanitizer.go | 8 +- internal/view/scale_extender.go | 33 +++- internal/view/sts.go | 77 ++++++--- internal/view/types.go | 5 +- internal/view/xray.go | 15 +- 73 files changed, 1362 insertions(+), 716 deletions(-) create mode 100644 change_logs/release_v0.24.11.md create mode 100644 internal/dao/log_items.go create mode 100644 internal/dao/log_items_test.go create mode 100644 internal/dao/log_options_test.go delete mode 100644 internal/view/log_dialog.go diff --git a/.goreleaser.yml b/.goreleaser.yml index 70316cba..0d69bb2f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -24,7 +24,7 @@ builds: ldflags: - -s -w -X github.com/derailed/k9s/cmd.version=v{{.Version}} -X github.com/derailed/k9s/cmd.commit={{.Commit}} -X github.com/derailed/k9s/cmd.date={{.Date}} archives: - - name_template: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}" + - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" replacements: darwin: Darwin linux: Linux diff --git a/Makefile b/Makefile index b0c39252..cb722f4d 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PACKAGE := github.com/derailed/$(NAME) GIT_REV ?= $(shell git rev-parse --short HEAD) SOURCE_DATE_EPOCH ?= $(shell date +%s) DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ") -VERSION ?= v0.24.10 +VERSION ?= v0.24.11 IMG_NAME := derailed/k9s IMAGE := ${IMG_NAME}:${VERSION} diff --git a/README.md b/README.md index 5a603a45..3c0d48e9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ for changes and offers subsequent commands to interact with your observed resour ## Note... -As you may know k9s is not pimped out by a big corporation with deep pockets. It is a complex OSS project that demands a lot of my time to maintain and support. K9s will always remain OSS and therefore free! That said if you feel, k9s makes your day to day Kubernetes journey a tad brighter, please consider sponsoring us or purchase a [K9sAlpha license](https://k9salpha.io). Your donations will go a long way in keeping our servers lights on and beers in our fridge! +As you may know k9s is not pimped out by a big corporation with deep pockets. It is a complex OSS project that demands a lot of my time to maintain and support. K9s will always remain OSS and therefore free! That said if you feel, k9s makes your day to day Kubernetes journey a tad brighter, please consider sponsoring us or purchase a [K9sAlpha license](https://k9salpha.io). Your donations will go a long way in keeping our servers lights on and beers in our fridge! **Thank you!** @@ -772,6 +772,16 @@ k9s: --- +## Contributors + +Without the contributions from these fine folks, this project would be a total dud! + + + + + +--- + ## Known Issues This is still work in progress! If something is broken or there's a feature diff --git a/change_logs/release_v0.24.10.md b/change_logs/release_v0.24.10.md index 6dbb1ad4..1ce6bbd9 100644 --- a/change_logs/release_v0.24.10.md +++ b/change_logs/release_v0.24.10.md @@ -6,7 +6,7 @@ Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better are as ever very much noted and appreciated! -If you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorhip program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) +If you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) diff --git a/change_logs/release_v0.24.11.md b/change_logs/release_v0.24.11.md new file mode 100644 index 00000000..4b6bd3a2 --- /dev/null +++ b/change_logs/release_v0.24.11.md @@ -0,0 +1,31 @@ + + +# Release v0.24.11 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better are as ever very much noted and appreciated! + +If you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +## Maintenance Release! + +> NOTE: Made a mistake with the last release binaries including a release tag. My bad as his caused a headache for the good folks managing the release upstream. Reverted the change on this drop! + +--- + +## Resolved Issues + +* [Issue #1163](https://github.com/derailed/k9s/issues/1163) Color for autocomplete text +* [Issue #1153](https://github.com/derailed/k9s/issues/1153) Crash when scaling a deployment with a custom view +* [Issue #1151](https://github.com/derailed/k9s/issues/1151) k9s does not use current namespace of current context +* [Issue #1140](https://github.com/derailed/k9s/issues/1140) Can no longer trigger cronjobs manually +* [Issue #1137](https://github.com/derailed/k9s/issues/1137) Unreadable container name +* [Issue #1132](https://github.com/derailed/k9s/issues/1132) Searching for regex not always working +* [Issue #1131](https://github.com/derailed/k9s/issues/1131) Changed release filenames starting k9s v0.24.10 + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/cmd/root.go b/cmd/root.go index 49415652..1a942c42 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -293,7 +293,3 @@ func initCertFlags() { "Bearer token for authentication to the API server", ) } - -func isBoolSet(b *bool) bool { - return b != nil && *b -} diff --git a/go.sum b/go.sum index ed2ad5eb..f22c4e39 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -13,17 +14,24 @@ cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible h1:KnPIugL51v3N3WwvaSmZbxukD1WuWXOiE9fRdu32f2I= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -57,9 +65,11 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= @@ -71,13 +81,16 @@ github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmy github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/squirrel v1.5.0 h1:JukIZisrUXadA9pl3rMkjhiamxiB0cXiu+HGp/Y8cY8= github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Masterminds/vcs v1.13.1 h1:NL3G1X7/7xduQtA2sJLpVpfHTNBALVNSjob6KEjPXNQ= github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/hcsshim v0.8.14 h1:lbPVK25c1cu5xTLITwpUcxoA9vKrKErASPYygvouJns= github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= @@ -87,41 +100,60 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= 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 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aws/aws-lambda-go v1.13.3 h1:SuCy7H3NLyp+1Mrfp+m80jcbi9KYWAs9/BXwppwRDzY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.29.32 h1:o4I8Qc+h9ht8NXvTHeXZH3EmtSUZ/PC0bg9Wawr+aTA= github.com/aws/aws-sdk-go v1.29.32/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= +github.com/aws/aws-sdk-go-v2 v0.18.0 h1:qZ+woO4SamnH/eEbjM2IDLhRNwIwND/RQyVlBLp3Jqg= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -131,27 +163,39 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3 h1:i8+1fuPLjSgAYXUyBlHNhFwjcfAsP4ufiuH1+PWkyDU= github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.3 h1:ijQT13JedHSHrQGWFcGEwzcNKrAGIiZ+jSD5QQG07SY= @@ -159,35 +203,53 @@ github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7 h1:6ejg6Lkk8dskcM7wQ28gONkukbQkM4qpj4RnYbpFzrI= github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de h1:dlfGmNcE3jDAecLqwKPMNX6nk2qh1c1Vg1/YTzpOOF4= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= 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 h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= 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 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= 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 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= 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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd h1:uVsMphB1eRx7xB1njzL3fuMdWRN8HtVzoUOItHMwv5c= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/deislabs/oras v0.10.0 h1:Eufbi8zVaULb7vYj5HKM9qv9qw6fJ7P75JSjn//gR0E= github.com/deislabs/oras v0.10.0/go.mod h1:N1UzE7rBa9qLyN4l8IlBTxc2PkrRcKgWQ3HTJvRnJRE= +github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY= github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/derailed/popeye v0.9.0 h1:0zP4BAzo94RUjrUkzgF962v0zL9B3xyopd7kU7tMxuc= github.com/derailed/popeye v0.9.0/go.mod h1:g3hudQlbEEChCA7U44fA+utTM9xQpD4pINUMQaiq5Gs= @@ -196,8 +258,11 @@ github.com/derailed/tcell/v2 v2.3.1-rc.2/go.mod h1:wegJ+SscH+jPjEQIAV/dI/grLTRm5 github.com/derailed/tview v0.6.1 h1:dB+9bO7r6a1Yg1HE+XNJj61hioauJnGBFq2biC5bjAk= github.com/derailed/tview v0.6.1/go.mod h1:5Wjopun0Jw3zxOFtafwc/GlrkFJix1hZz1oQetWpnwE= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v20.10.3+incompatible h1:WVEgoV/GpsTK5hruhHdYi79blQ+nmcm+7Ru/ZuiF+7E= github.com/docker/cli v20.10.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -215,14 +280,20 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arX github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/drone/envsubst v1.0.2 h1:dpYLMAspQHW0a8dZpLRKe9jCNvIGZPhCPrycZzIHdqo= github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 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= @@ -231,7 +302,9 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/emicklei/go-restful v2.15.0+incompatible h1:8KpYO/Xl/ZudZs5RNOEhWMBY4hmzlZhhRd9cu+jrZP4= github.com/emicklei/go-restful v2.15.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= @@ -245,7 +318,9 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQWj4T+rfKHYCHxRHCtRxhKKjRidVw= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 h1:a9ENSRDFBUPkJ5lCgVZh26+ZbGyoVJG7yb5SSzF5H54= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= @@ -260,15 +335,20 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -293,6 +373,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= @@ -305,16 +386,22 @@ github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYi github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.13.3 h1:4A5GLGAJTSuELw1NThqY5bINYB+mqrln+kF5C2vuyCs= github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= 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 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -326,6 +413,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -342,9 +430,13 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= +github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= +github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= @@ -359,26 +451,33 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 h1:SRgJV+IoxM5MKyFdlSUeNy6/ycRUF2yBAKdAQswoHUk= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= @@ -388,52 +487,78 @@ github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= 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= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0 h1:HXNYlRkkM/t+Y/Yhxtwcy02dlYwIaoxzvxPnS+cqy78= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0 h1:UOxjlb4xVNF93jak1mzzoBatyFju9nrkxpVwIp/QqxQ= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0 h1:0U6+BtN6LhaYuTnIJq4Wyq5cpn6O2kWrxAtcqBmYY6w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/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 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -443,6 +568,7 @@ github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -451,20 +577,28 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -480,12 +614,16 @@ github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 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/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743 h1:143Bb8f8DuGWck/xpNUOckBVYfFbBTnLevfRZ1aVVqo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1 h1:vi1F1IQ8N7hNWytK9DpJsUfQhGuNSc19z330K6vl4zk= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lyft/protoc-gen-validate v0.0.13 h1:KNt/RhmQTOLr7Aj8PsJ7mTronaFyx80mRTT9qF261dA= 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 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= @@ -495,6 +633,7 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= @@ -503,12 +642,14 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-oci8 v0.0.7 h1:BBXYpvzPO43QNTLDEivPFteeFZ9nKA6JQ6eifpxOmio= github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do= @@ -516,20 +657,27 @@ github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsO github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= 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/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -546,22 +694,35 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 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 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= 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/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2 h1:i2Ly0B+1+rzNZHHWtD4ZwKi+OU5l+uQo1iDHZ2PmiIc= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1 h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3 h1:6JrEfig+HzTH85yxzhSVbjHRJv9cn0p6n3IngIcM5/k= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47 h1:4DQRPj35Y41WogBxyhOXlrI37nzGlyEcsforeudyYPQ= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= 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= @@ -572,6 +733,7 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -583,6 +745,7 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec h1:S6wtb5ie7KeMcuEaESj0RoSmpyGfvOSuunmKEdX7wg8= github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14= @@ -590,18 +753,28 @@ github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c h1:9RGaDpUySgRsc github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c/go.mod h1:u/KO+e43wkagC0lqM1eaqNEWEBdg08Q1ugP/idj39MM= github.com/openfaas/faas-provider v0.15.0 h1:3x5ma90FL7AqP4NOD6f03AY24y3xBeVF6xGLUx6Xrlc= github.com/openfaas/faas-provider v0.15.0/go.mod h1:8Fagi2UeMfL+gZAqZWSMQg86i+w1+hBOKtwKRP5sLFI= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible h1:2WnRzIquHa5QxaJKShDkLM+sc0JPuwhXzK8OYOyt3Vg= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -610,15 +783,19 @@ github.com/petergtz/pegomock v2.9.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/ github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 h1:0XM1XL/OFFJjXsYXlG30spTkV/E9+gmd5GD1w2HE8xM= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -655,19 +832,23 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/hey v0.1.4 h1:hhc8GIqHN4+rPFZvkM9lkCQGi7da0sINM83xxpFkbPA= github.com/rakyll/hey v0.1.4/go.mod h1:nAOTOo+L52KB9SZq/M6J18kxjto4yVtXQDjU2HgjUPI= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0 h1:LUa41nrWTQNGhzdsZ5lTnkwbNjj6rXTdazA1cSdjkOY= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/rs/zerolog v1.22.0 h1:XrVUjV4K+izZpKXZHlPrYQiDtmdGiCylnT4i43AAWxg= @@ -676,17 +857,23 @@ github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 h1:HXr/qUllAWv9 github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -694,13 +881,19 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= 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 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= @@ -712,6 +905,7 @@ github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -721,12 +915,16 @@ 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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a h1:AhmOdSHeswKHBjhsLs/7+1voOxT+LLrSk/Nxvk35fug= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -735,13 +933,18 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -749,9 +952,12 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= @@ -759,13 +965,16 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -776,13 +985,17 @@ go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4= go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= 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= @@ -812,8 +1025,10 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -824,14 +1039,17 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -999,6 +1217,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1016,6 +1235,7 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1024,6 +1244,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= 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= @@ -1072,27 +1293,36 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= 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 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1118,6 +1348,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= @@ -1141,15 +1372,18 @@ k8s.io/client-go v0.20.5 h1:dJGtYUvFrFGjQ+GjXEIby0gZWdlAOc0xJBJqY3VyDxA= k8s.io/client-go v0.20.5/go.mod h1:Ee5OOMMYvlH8FCZhDsacjMlCBwetbGZETwo1OA+e6Zw= k8s.io/code-generator v0.18.8/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= +k8s.io/code-generator v0.20.5 h1:qQp2F2ZnosUqeV7ZqKE6bQnf7x9Ps9RFfKZxw1r5HsM= k8s.io/code-generator v0.20.5/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= k8s.io/component-base v0.20.5 h1:8BZQKLJGhWrxtB7kIOEejKDtAKr1HOYvB0PZNeTyLS0= k8s.io/component-base v0.20.5/go.mod h1:l0isoBLGyQKwRoTWbPHR6jNDd3/VqQD43cNlsjddGng= k8s.io/component-helpers v0.20.2/go.mod h1:qeM6iAWGqIr+WE8n2QW2OK9XkpZkPNTxAoEv9jl40/I= +k8s.io/component-helpers v0.20.5 h1:JmmGqBM7CaJRUKL6oVFoiM7BT2hE9cxg/yjrPkMhSbk= k8s.io/component-helpers v0.20.5/go.mod h1:AzTdoPj6YAN2SUfhBX/FUUU3ntfFuse03q/VMLovEsE= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded h1:JApXBKYyB7l9xx+DK7/+mFjC7A9Bt5A93FPvFD0HIFE= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -1173,17 +1407,23 @@ k8s.io/metrics v0.20.5/go.mod h1:vsptOayjKWKWHvWR1vFQY++vxydzaEo/2+JC7kSDKPU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14 h1:TihvEz9MPj2u0KWds6E2OBUXfwaL4qRJ33c7HGiJpqk= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/client/config.go b/internal/client/config.go index 7934db2e..230244ac 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -27,7 +27,7 @@ type Config struct { rawConfig *clientcmdapi.Config restConfig *restclient.Config mutex *sync.RWMutex - OverrideNS bool + OverrideNS bool } // NewConfig returns a new k8s config or an error if the flags are invalid. diff --git a/internal/client/helpers.go b/internal/client/helpers.go index 581b30e1..6f45b604 100644 --- a/internal/client/helpers.go +++ b/internal/client/helpers.go @@ -53,6 +53,11 @@ func Namespaced(p string) (string, string) { return strings.Trim(ns, "/"), n } +// CoFQN returns a fully qualified container name. +func CoFQN(m metav1.ObjectMeta, co string) string { + return MetaFQN(m) + ":" + co +} + // FQN returns a fully qualified resource name. func FQN(ns, n string) string { if ns == "" { diff --git a/internal/config/alias.go b/internal/config/alias.go index 3ace928e..57c31d90 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -106,19 +106,17 @@ func (a *Aliases) Load() error { // LoadFileAliases loads alias from a given file. func (a *Aliases) LoadFileAliases(path string) error { f, err := ioutil.ReadFile(path) - if err != nil { - return nil - } + if err == nil { + var aa Aliases + if err := yaml.Unmarshal(f, &aa); err != nil { + return err + } - var aa Aliases - if err := yaml.Unmarshal(f, &aa); err != nil { - return err - } - - a.mx.Lock() - defer a.mx.Unlock() - for k, v := range aa.Alias { - a.Alias[k] = v + a.mx.Lock() + defer a.mx.Unlock() + for k, v := range aa.Alias { + a.Alias[k] = v + } } return nil diff --git a/internal/config/helpers.go b/internal/config/helpers.go index a1d9ef57..e30599cd 100644 --- a/internal/config/helpers.go +++ b/internal/config/helpers.go @@ -69,6 +69,7 @@ func EnsureFullPath(path string, mod os.FileMode) { } } +// IsBoolSet checks if a bool prt is set. func IsBoolSet(b *bool) bool { return b != nil && *b } diff --git a/internal/config/k9s.go b/internal/config/k9s.go index 6556246a..ca8e5e3e 100644 --- a/internal/config/k9s.go +++ b/internal/config/k9s.go @@ -43,6 +43,7 @@ func NewK9s() *K9s { } } +// ActiveCluster initializes the active cluster is not present. func (k *K9s) ActivateCluster() { if _, ok := k.Clusters[k.CurrentCluster]; ok { return diff --git a/internal/config/styles.go b/internal/config/styles.go index 1012bd87..86861b25 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -42,7 +42,7 @@ type ( Dialog Dialog `yaml:"dialog"` } - // Helps tracks help styles. + // Help tracks help styles. Help struct { FgColor Color `yaml:"fgColor"` BgColor Color `yaml:"bgColor"` diff --git a/internal/dao/container.go b/internal/dao/container.go index 20eacde7..59a14128 100644 --- a/internal/dao/container.go +++ b/internal/dao/container.go @@ -55,7 +55,7 @@ func (c *Container) List(ctx context.Context, _ string) ([]runtime.Object, error } // TailLogs tails a given container logs -func (c *Container) TailLogs(ctx context.Context, logChan LogChan, opts LogOptions) error { +func (c *Container) TailLogs(ctx context.Context, logChan LogChan, opts *LogOptions) error { po := Pod{} po.Init(c.Factory, client.NewGVR("v1/pods")) diff --git a/internal/dao/cronjob.go b/internal/dao/cronjob.go index d922cc43..24b4e96c 100644 --- a/internal/dao/cronjob.go +++ b/internal/dao/cronjob.go @@ -111,7 +111,7 @@ func (c *CronJob) ScanSA(ctx context.Context, fqn string, wait bool) (Refs, erro return refs, nil } -// Suspend toggles suspend/resume on a CronJob. +// ToggleSuspend toggles suspend/resume on a CronJob. func (c *CronJob) ToggleSuspend(ctx context.Context, path string) error { ns, _ := client.Namespaced(path) diff --git a/internal/dao/dp.go b/internal/dao/dp.go index e136a202..28aa943a 100644 --- a/internal/dao/dp.go +++ b/internal/dao/dp.go @@ -97,7 +97,7 @@ func (d *Deployment) Restart(ctx context.Context, path string) error { } // TailLogs tail logs for all pods represented by this Deployment. -func (d *Deployment) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (d *Deployment) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { dp, err := d.Load(d.Factory, opts.Path) if err != nil { return err diff --git a/internal/dao/ds.go b/internal/dao/ds.go index b2dd2754..d46d4f88 100644 --- a/internal/dao/ds.go +++ b/internal/dao/ds.go @@ -73,7 +73,7 @@ func (d *DaemonSet) Restart(ctx context.Context, path string) error { } // TailLogs tail logs for all pods represented by this DaemonSet. -func (d *DaemonSet) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (d *DaemonSet) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { ds, err := d.GetInstance(opts.Path) if err != nil { return err @@ -86,7 +86,7 @@ func (d *DaemonSet) TailLogs(ctx context.Context, c LogChan, opts LogOptions) er return podLogs(ctx, c, ds.Spec.Selector.MatchLabels, opts) } -func podLogs(ctx context.Context, c LogChan, sel map[string]string, opts LogOptions) error { +func podLogs(ctx context.Context, c LogChan, sel map[string]string, opts *LogOptions) error { f, ok := ctx.Value(internal.KeyFactory).(*watch.Factory) if !ok { return errors.New("expecting a context factory") @@ -115,6 +115,7 @@ func podLogs(ctx context.Context, c LogChan, sel map[string]string, opts LogOpti if err != nil { return err } + opts = opts.Clone() opts.Path = client.FQN(pod.Namespace, pod.Name) if err := po.TailLogs(ctx, c, opts); err != nil { return err diff --git a/internal/dao/job.go b/internal/dao/job.go index 3fd35252..43d531b5 100644 --- a/internal/dao/job.go +++ b/internal/dao/job.go @@ -57,7 +57,7 @@ func (j *Job) List(ctx context.Context, ns string) ([]runtime.Object, error) { } // TailLogs tail logs for all pods represented by this Job. -func (j *Job) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (j *Job) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { o, err := j.Factory.Get(j.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err diff --git a/internal/dao/log_item.go b/internal/dao/log_item.go index f8815505..7242b265 100644 --- a/internal/dao/log_item.go +++ b/internal/dao/log_item.go @@ -3,14 +3,10 @@ package dao import ( "bytes" "fmt" - "math/rand" "regexp" - "strings" "time" "github.com/derailed/k9s/internal/color" - "github.com/rs/zerolog/log" - "github.com/sahilm/fuzzy" ) // LogChan represents a channel for logs. @@ -26,13 +22,12 @@ type LogItem struct { // NewLogItem returns a new item. func NewLogItem(b []byte) *LogItem { space := []byte(" ") - var l LogItem - cols := bytes.Split(b[:len(b)-1], space) - l.Timestamp = string(cols[0]) - l.Bytes = bytes.Join(cols[1:], space) - return &l + return &LogItem{ + Timestamp: string(cols[0]), + Bytes: bytes.Join(cols[1:], space), + } } // NewLogItemFromString returns a new item. @@ -91,135 +86,20 @@ func (l *LogItem) Render(paint int, showTime bool) []byte { bb = append(bb, ' ') } + var hasPod bool if l.Pod != "" { bb = append(bb, color.ANSIColorize(l.Pod, paint)...) - bb = append(bb, ':') + hasPod = true } if !l.SingleContainer && l.Container != "" { + if hasPod { + bb = append(bb, ':') + } bb = append(bb, color.ANSIColorize(l.Container, paint)...) bb = append(bb, ' ') + } else if hasPod { + bb = append(bb, ' ') } return append(bb, escPattern.ReplaceAll(l.Bytes, matcher)...) } - -func colorFor(n string) int { - var sum int - for _, r := range n { - sum += int(r) - } - - c := sum % 256 - if c == 0 { - c = 207 + rand.Intn(10) - } - return c -} - -// ---------------------------------------------------------------------------- - -// LogItems represents a collection of log items. -type LogItems []*LogItem - -// Lines returns a collection of log lines. -func (l LogItems) Lines(showTime bool) [][]byte { - ll := make([][]byte, len(l)) - for i, item := range l { - ll[i] = item.Render(0, showTime) - } - - return ll -} - -// StrLines returns a collection of log lines. -func (l LogItems) StrLines(showTime bool) []string { - ll := make([]string, len(l)) - for i, item := range l { - ll[i] = string(item.Render(0, showTime)) - } - - return ll -} - -// Render returns logs as a collection of strings. -func (l LogItems) Render(showTime bool, ll [][]byte) { - colors := make(map[string]int, len(l)) - for i, item := range l { - info := item.ID() - color, ok := colors[info] - if !ok { - color = colorFor(info) - colors[info] = color - } - ll[i] = item.Render(color, showTime) - } -} - -// DumpDebug for debugging -func (l LogItems) DumpDebug(m string) { - fmt.Println(m + strings.Repeat("-", 50)) - for i, line := range l { - fmt.Println(i, string(line.Bytes)) - } -} - -// Filter filters out log items based on given filter. -func (l LogItems) Filter(q string, showTime bool) ([]int, [][]int, error) { - if q == "" { - return nil, nil, nil - } - if IsFuzzySelector(q) { - mm, ii := l.fuzzyFilter(strings.TrimSpace(q[2:]), showTime) - return mm, ii, nil - } - matches, indices, err := l.filterLogs(q, showTime) - if err != nil { - log.Error().Err(err).Msgf("Logs filter failed") - return nil, nil, err - } - return matches, indices, nil -} - -func (l LogItems) fuzzyFilter(q string, showTime bool) ([]int, [][]int) { - q = strings.TrimSpace(q) - matches, indices := make([]int, 0, len(l)), make([][]int, 0, 10) - mm := fuzzy.Find(q, l.StrLines(showTime)) - for _, m := range mm { - matches = append(matches, m.Index) - indices = append(indices, m.MatchedIndexes) - } - - return matches, indices -} - -func (l LogItems) filterLogs(q string, showTime bool) ([]int, [][]int, error) { - var invert bool - if IsInverseSelector(q) { - invert = true - q = q[1:] - } - rx, err := regexp.Compile(`(?i)` + q) - if err != nil { - return nil, nil, err - } - matches, indices := make([]int, 0, len(l)), make([][]int, 0, 10) - for i, line := range l.Lines(showTime) { - locs := rx.FindIndex(line) - if locs != nil && invert { - continue - } - if locs == nil && !invert { - continue - } - matches = append(matches, i) - ii := make([]int, 0, 10) - for i := 0; i < len(locs); i += 2 { - for j := locs[i]; j < locs[i+1]; j++ { - ii = append(ii, j) - } - } - indices = append(indices, ii) - } - - return matches, indices, nil -} diff --git a/internal/dao/log_item_test.go b/internal/dao/log_item_test.go index 56ac3ac9..73452061 100644 --- a/internal/dao/log_item_test.go +++ b/internal/dao/log_item_test.go @@ -6,125 +6,9 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" - "github.com/rs/zerolog" "github.com/stretchr/testify/assert" ) -func init() { - zerolog.SetGlobalLevel(zerolog.FatalLevel) -} - -func TestLogItemsFilter(t *testing.T) { - uu := map[string]struct { - q string - opts dao.LogOptions - e []int - err error - }{ - "empty": { - opts: dao.LogOptions{}, - }, - "pod-name": { - q: "blee", - opts: dao.LogOptions{ - Path: "fred/blee", - Container: "c1", - }, - e: []int{0, 1, 2}, - }, - "container-name": { - q: "c1", - opts: dao.LogOptions{ - Path: "fred/blee", - Container: "c1", - }, - e: []int{0, 1, 2}, - }, - "message": { - q: "zorg", - opts: dao.LogOptions{ - Path: "fred/blee", - Container: "c1", - }, - e: []int{2}, - }, - "fuzzy": { - q: "-f zorg", - opts: dao.LogOptions{ - Path: "fred/blee", - Container: "c1", - }, - e: []int{2}, - }, - } - - for k := range uu { - u := uu[k] - ii := dao.LogItems{ - dao.NewLogItem([]byte(fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", "Testing 1,2,3..."))), - dao.NewLogItemFromString("Bumble bee tuna"), - dao.NewLogItemFromString("Jean Batiste Emmanuel Zorg"), - } - t.Run(k, func(t *testing.T) { - _, n := client.Namespaced(u.opts.Path) - for _, i := range ii { - i.Pod, i.Container = n, u.opts.Container - } - res, _, err := ii.Filter(u.q, false) - assert.Equal(t, u.err, err) - if err == nil { - assert.Equal(t, u.e, res) - } - }) - } -} - -func TestLogItemsRender(t *testing.T) { - uu := map[string]struct { - opts dao.LogOptions - e string - }{ - "empty": { - opts: dao.LogOptions{}, - e: "Testing 1,2,3...", - }, - "container": { - opts: dao.LogOptions{ - Container: "fred", - }, - e: "\x1b[38;5;161mfred\x1b[0m Testing 1,2,3...", - }, - "pod": { - opts: dao.LogOptions{ - Path: "blee/fred", - Container: "blee", - }, - e: "\x1b[38;5;161mfred\x1b[0m:\x1b[38;5;161mblee\x1b[0m Testing 1,2,3...", - }, - "full": { - opts: dao.LogOptions{ - Path: "blee/fred", - Container: "blee", - ShowTimestamp: true, - }, - e: "\x1b[38;5;106m2018-12-14T10:36:43.326972-07:00\x1b[0m \x1b[38;5;161mfred\x1b[0m:\x1b[38;5;161mblee\x1b[0m Testing 1,2,3...", - }, - } - - s := []byte(fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", "Testing 1,2,3...")) - ii := dao.LogItems{dao.NewLogItem(s)} - for k := range uu { - u := uu[k] - _, n := client.Namespaced(u.opts.Path) - ii[0].Pod, ii[0].Container = n, u.opts.Container - t.Run(k, func(t *testing.T) { - res := make([][]byte, 1) - ii.Render(u.opts.ShowTimestamp, res) - assert.Equal(t, u.e, string(res[0])) - }) - } -} - func TestLogItemEmpty(t *testing.T) { uu := map[string]struct { s string @@ -160,16 +44,18 @@ func TestLogItemRender(t *testing.T) { }, "pod": { opts: dao.LogOptions{ - Path: "blee/fred", - Container: "blee", + Path: "blee/fred", + Container: "blee", + SingleContainer: true, }, e: "\x1b[38;5;0mfred\x1b[0m:\x1b[38;5;0mblee\x1b[0m Testing 1,2,3...", }, "full": { opts: dao.LogOptions{ - Path: "blee/fred", - Container: "blee", - ShowTimestamp: true, + Path: "blee/fred", + Container: "blee", + SingleContainer: true, + ShowTimestamp: true, }, e: "\x1b[38;5;106m2018-12-14T10:36:43.326972-07:00\x1b[0m \x1b[38;5;0mfred\x1b[0m:\x1b[38;5;0mblee\x1b[0m Testing 1,2,3...", }, diff --git a/internal/dao/log_items.go b/internal/dao/log_items.go new file mode 100644 index 00000000..73a66cb6 --- /dev/null +++ b/internal/dao/log_items.go @@ -0,0 +1,215 @@ +package dao + +import ( + "fmt" + "regexp" + "strings" + "sync" + + "github.com/gdamore/tcell/v2" + "github.com/sahilm/fuzzy" +) + +var colorPalette = []tcell.Color{ + tcell.ColorTeal, + tcell.ColorGreen, + tcell.ColorPurple, + tcell.ColorLime, + tcell.ColorBlue, + tcell.ColorYellow, + tcell.ColorFuchsia, + tcell.ColorAqua, +} + +// LogItems represents a collection of log items. +type LogItems struct { + items []*LogItem + colors map[string]tcell.Color + mx sync.RWMutex +} + +// NewLogItems returns a new instance. +func NewLogItems() *LogItems { + return &LogItems{ + colors: make(map[string]tcell.Color), + } +} + +// Len returns the items length. +func (l *LogItems) Items() []*LogItem { + l.mx.RLock() + defer l.mx.RUnlock() + + return l.items +} + +// Len returns the items length. +func (l *LogItems) Len() int { + l.mx.RLock() + defer l.mx.RUnlock() + + return len(l.items) +} + +// Clear removes all items. +func (l *LogItems) Clear() { + l.mx.Lock() + defer l.mx.Unlock() + + l.items = nil + for k := range l.colors { + delete(l.colors, k) + } +} + +// Shift scrolls the lines by one. +func (l *LogItems) Shift(i *LogItem) { + l.mx.Lock() + defer l.mx.Unlock() + + l.items = append(l.items[1:], i) +} + +// Subset return a subset of logitems. +func (l *LogItems) Subset(index int) *LogItems { + l.mx.RLock() + defer l.mx.RUnlock() + + return &LogItems{ + items: l.items[index:], + colors: l.colors, + } +} + +// Merge merges two logitems list. +func (l *LogItems) Merge(n *LogItems) { + l.mx.Lock() + defer l.mx.Unlock() + + l.items = append(l.items, n.items...) + for k, v := range n.colors { + l.colors[k] = v + } +} + +// Add augments the items. +func (l *LogItems) Add(ii ...*LogItem) { + l.mx.Lock() + defer l.mx.Unlock() + + l.items = append(l.items, ii...) +} + +// Lines returns a collection of log lines. +func (l *LogItems) Lines(showTime bool) [][]byte { + l.mx.Lock() + defer l.mx.Unlock() + + ll := make([][]byte, len(l.items)) + for i, item := range l.items { + color := l.colors[item.ID()] + ll[i] = item.Render(int(color-tcell.ColorValid), showTime) + } + + return ll +} + +// StrLines returns a collection of log lines. +func (l *LogItems) StrLines(showTime bool) []string { + l.mx.Lock() + defer l.mx.Unlock() + + ll := make([]string, len(l.items)) + for i, item := range l.items { + ll[i] = string(item.Render(0, showTime)) + } + + return ll +} + +// Render returns logs as a collection of strings. +func (l *LogItems) Render(showTime bool, ll [][]byte) { + index := len(l.colors) + for i, item := range l.items { + id := item.ID() + color, ok := l.colors[id] + if !ok { + if index >= len(colorPalette) { + index = 0 + } + color = colorPalette[index] + l.colors[id] = color + index++ + } + ll[i] = item.Render(int(color-tcell.ColorValid), showTime) + } +} + +// DumpDebug for debugging +func (l *LogItems) DumpDebug(m string) { + fmt.Println(m + strings.Repeat("-", 50)) + for i, line := range l.items { + fmt.Println(i, string(line.Bytes)) + } +} + +// Filter filters out log items based on given filter. +func (l *LogItems) Filter(q string, showTime bool) ([]int, [][]int, error) { + if q == "" { + return nil, nil, nil + } + if IsFuzzySelector(q) { + mm, ii := l.fuzzyFilter(strings.TrimSpace(q[2:]), showTime) + return mm, ii, nil + } + matches, indices, err := l.filterLogs(q, showTime) + if err != nil { + return nil, nil, err + } + + return matches, indices, nil +} + +func (l *LogItems) fuzzyFilter(q string, showTime bool) ([]int, [][]int) { + q = strings.TrimSpace(q) + matches, indices := make([]int, 0, len(l.items)), make([][]int, 0, 10) + mm := fuzzy.Find(q, l.StrLines(showTime)) + for _, m := range mm { + matches = append(matches, m.Index) + indices = append(indices, m.MatchedIndexes) + } + + return matches, indices +} + +func (l *LogItems) filterLogs(q string, showTime bool) ([]int, [][]int, error) { + var invert bool + if IsInverseSelector(q) { + invert = true + q = q[1:] + } + rx, err := regexp.Compile(`(?i)` + q) + if err != nil { + return nil, nil, err + } + matches, indices := make([]int, 0, len(l.items)), make([][]int, 0, 10) + for i, line := range l.Lines(showTime) { + locs := rx.FindIndex(line) + if locs != nil && invert { + continue + } + if locs == nil && !invert { + continue + } + matches = append(matches, i) + ii := make([]int, 0, 10) + for i := 0; i < len(locs); i += 2 { + for j := locs[i]; j < locs[i+1]; j++ { + ii = append(ii, j) + } + } + indices = append(indices, ii) + } + + return matches, indices, nil +} diff --git a/internal/dao/log_items_test.go b/internal/dao/log_items_test.go new file mode 100644 index 00000000..b783081f --- /dev/null +++ b/internal/dao/log_items_test.go @@ -0,0 +1,128 @@ +package dao_test + +import ( + "fmt" + "testing" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" +) + +func init() { + zerolog.SetGlobalLevel(zerolog.FatalLevel) +} + +func TestLogItemsFilter(t *testing.T) { + uu := map[string]struct { + q string + opts dao.LogOptions + e []int + err error + }{ + "empty": { + opts: dao.LogOptions{}, + }, + "pod-name": { + q: "blee", + opts: dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + }, + e: []int{0, 1, 2}, + }, + "container-name": { + q: "c1", + opts: dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + }, + e: []int{0, 1, 2}, + }, + "message": { + q: "zorg", + opts: dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + }, + e: []int{2}, + }, + "fuzzy": { + q: "-f zorg", + opts: dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + }, + e: []int{2}, + }, + } + + for k := range uu { + u := uu[k] + ii := dao.NewLogItems() + ii.Add( + dao.NewLogItem([]byte(fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", "Testing 1,2,3..."))), + dao.NewLogItemFromString("Bumble bee tuna"), + dao.NewLogItemFromString("Jean Batiste Emmanuel Zorg"), + ) + t.Run(k, func(t *testing.T) { + _, n := client.Namespaced(u.opts.Path) + for _, i := range ii.Items() { + i.Pod, i.Container = n, u.opts.Container + } + res, _, err := ii.Filter(u.q, false) + assert.Equal(t, u.err, err) + if err == nil { + assert.Equal(t, u.e, res) + } + }) + } +} + +func TestLogItemsRender(t *testing.T) { + uu := map[string]struct { + opts dao.LogOptions + e string + }{ + "empty": { + opts: dao.LogOptions{}, + e: "Testing 1,2,3...", + }, + "container": { + opts: dao.LogOptions{ + Container: "fred", + }, + e: "\x1b[38;5;6mfred\x1b[0m Testing 1,2,3...", + }, + "pod": { + opts: dao.LogOptions{ + Path: "blee/fred", + Container: "blee", + }, + e: "\x1b[38;5;6mfred\x1b[0m:\x1b[38;5;6mblee\x1b[0m Testing 1,2,3...", + }, + "full": { + opts: dao.LogOptions{ + Path: "blee/fred", + Container: "blee", + ShowTimestamp: true, + }, + e: "\x1b[38;5;106m2018-12-14T10:36:43.326972-07:00\x1b[0m \x1b[38;5;6mfred\x1b[0m:\x1b[38;5;6mblee\x1b[0m Testing 1,2,3...", + }, + } + + s := []byte(fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", "Testing 1,2,3...")) + for k := range uu { + ii := dao.NewLogItems() + ii.Add(dao.NewLogItem(s)) + u := uu[k] + _, n := client.Namespaced(u.opts.Path) + ii.Items()[0].Pod, ii.Items()[0].Container = n, u.opts.Container + t.Run(k, func(t *testing.T) { + res := make([][]byte, 1) + ii.Render(u.opts.ShowTimestamp, res) + assert.Equal(t, u.e, string(res[0])) + }) + } +} diff --git a/internal/dao/log_options.go b/internal/dao/log_options.go index 36a8063b..0389efda 100644 --- a/internal/dao/log_options.go +++ b/internal/dao/log_options.go @@ -10,32 +10,65 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// LogOptions represent logger options. +// LogOptions represents logger options. type LogOptions struct { - Path string - Container string - Lines int64 - Previous bool - SingleContainer bool - MultiPods bool - ShowTimestamp bool - SinceTime string - SinceSeconds int64 - In, Out string + Path string + Container string + DefaultContainer string + SinceTime string + Lines int64 + SinceSeconds int64 + Previous bool + SingleContainer bool + MultiPods bool + ShowTimestamp bool + AllContainers bool } // Info returns the option pod and container info. -func (o LogOptions) Info() string { +func (o *LogOptions) Info() string { return fmt.Sprintf("%q::%q", o.Path, o.Container) } +func (o *LogOptions) Clone() *LogOptions { + return &LogOptions{ + Path: o.Path, + Container: o.Container, + DefaultContainer: o.DefaultContainer, + Lines: o.Lines, + Previous: o.Previous, + SingleContainer: o.SingleContainer, + MultiPods: o.MultiPods, + ShowTimestamp: o.ShowTimestamp, + SinceTime: o.SinceTime, + SinceSeconds: o.SinceSeconds, + AllContainers: o.AllContainers, + } +} + // HasContainer checks if a container is present. -func (o LogOptions) HasContainer() bool { +func (o *LogOptions) HasContainer() bool { return o.Container != "" } +// ToggleAllContainers toggles single or all-containers if possible. +func (o *LogOptions) ToggleAllContainers() { + if o.SingleContainer { + return + } + o.AllContainers = !o.AllContainers + if o.AllContainers { + o.DefaultContainer, o.Container = o.Container, "" + return + } + + if o.DefaultContainer != "" { + o.Container = o.DefaultContainer + } +} + // ToPodLogOptions returns pod log options. -func (o LogOptions) ToPodLogOptions() *v1.PodLogOptions { +func (o *LogOptions) ToPodLogOptions() *v1.PodLogOptions { opts := v1.PodLogOptions{ Follow: true, Timestamps: true, @@ -43,14 +76,15 @@ func (o LogOptions) ToPodLogOptions() *v1.PodLogOptions { Previous: o.Previous, TailLines: &o.Lines, } - if o.SinceSeconds < 0 { return &opts } + if o.SinceSeconds != 0 { - opts.SinceSeconds = &o.SinceSeconds + opts.SinceSeconds, opts.SinceTime = &o.SinceSeconds, nil return &opts } + if o.SinceTime == "" { return &opts } @@ -62,7 +96,7 @@ func (o LogOptions) ToPodLogOptions() *v1.PodLogOptions { } // FixedSizeName returns a normalize fixed size pod name if possible. -func (o LogOptions) FixedSizeName() string { +func (o *LogOptions) FixedSizeName() string { _, n := client.Namespaced(o.Path) tokens := strings.Split(n, "-") if len(tokens) < 3 { @@ -77,7 +111,7 @@ func (o LogOptions) FixedSizeName() string { } // DecorateLog add a log header to display po/co information along with the log message. -func (o LogOptions) DecorateLog(bytes []byte) *LogItem { +func (o *LogOptions) DecorateLog(bytes []byte) *LogItem { item := NewLogItem(bytes) if len(bytes) == 0 { return item diff --git a/internal/dao/log_options_test.go b/internal/dao/log_options_test.go new file mode 100644 index 00000000..71a594e6 --- /dev/null +++ b/internal/dao/log_options_test.go @@ -0,0 +1,43 @@ +package dao_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/dao" + "github.com/stretchr/testify/assert" +) + +func TestLogOptionsToggleAllContainers(t *testing.T) { + uu := map[string]struct { + opts dao.LogOptions + co string + want bool + }{ + "empty": { + opts: dao.LogOptions{}, + want: true, + }, + "container": { + opts: dao.LogOptions{Container: "blee"}, + want: true, + }, + "default-container": { + opts: dao.LogOptions{AllContainers: true}, + co: "blee", + }, + "single-container": { + opts: dao.LogOptions{Container: "blee", SingleContainer: true}, + co: "blee", + }, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + u.opts.DefaultContainer = "blee" + u.opts.ToggleAllContainers() + assert.Equal(t, u.want, u.opts.AllContainers) + assert.Equal(t, u.co, u.opts.Container) + }) + } +} diff --git a/internal/dao/pod.go b/internal/dao/pod.go index b1942e05..8572ec40 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -177,11 +177,11 @@ func (p *Pod) GetInstance(fqn string) (*v1.Pod, error) { } // TailLogs tails a given container logs -func (p *Pod) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (p *Pod) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { log.Debug().Msgf("TAIL-LOGS for %q:%q", opts.Path, opts.Container) fac, ok := ctx.Value(internal.KeyFactory).(*watch.Factory) if !ok { - return errors.New("Expecting an informer") + return errors.New("No factory in context") } o, err := fac.Get(p.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { @@ -192,39 +192,40 @@ func (p *Pod) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { return err } - if opts.HasContainer() { - opts.SingleContainer = true - return tailLogs(ctx, p, c, opts) - } - - if defaultContainer, ok := getDefaultLogContainer(po); ok { - opts.SingleContainer = true - opts.Container = defaultContainer - return tailLogs(ctx, p, c, opts) - } - if len(po.Spec.InitContainers)+len(po.Spec.Containers) == 1 { opts.SingleContainer = true } + if co, ok := GetDefaultLogContainer(po.ObjectMeta, po.Spec); ok && !opts.AllContainers { + opts.DefaultContainer = co + return tailLogs(ctx, p, c, opts) + } + + if opts.HasContainer() && !opts.AllContainers { + return tailLogs(ctx, p, c, opts) + } + var tailed bool for _, co := range po.Spec.InitContainers { - opts.Container = co.Name - if err := tailLogs(ctx, p, c, opts); err != nil { + o := opts.Clone() + o.Container = co.Name + if err := tailLogs(ctx, p, c, o); err != nil { return err } tailed = true } for _, co := range po.Spec.Containers { - opts.Container = co.Name - if err := tailLogs(ctx, p, c, opts); err != nil { + o := opts.Clone() + o.Container = co.Name + if err := tailLogs(ctx, p, c, o); err != nil { return err } tailed = true } for _, co := range po.Spec.EphemeralContainers { - opts.Container = co.Name - if err := tailLogs(ctx, p, c, opts); err != nil { + o := opts.Clone() + o.Container = co.Name + if err := tailLogs(ctx, p, c, o); err != nil { return err } tailed = true @@ -325,8 +326,8 @@ func (p *Pod) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, error // ---------------------------------------------------------------------------- // Helpers... -func tailLogs(ctx context.Context, logger Logger, c LogChan, opts LogOptions) error { - log.Debug().Msgf("Tailing logs for %q:%q", opts.Path, opts.Container) +func tailLogs(ctx context.Context, logger Logger, c LogChan, opts *LogOptions) error { + log.Debug().Msgf("Tailing logs for %#v", opts) var ( err error @@ -366,7 +367,7 @@ done: return nil } -func readLogs(stream io.ReadCloser, c LogChan, opts LogOptions) { +func readLogs(stream io.ReadCloser, c LogChan, opts *LogOptions) { defer func() { log.Debug().Msgf(">>> Closing stream %s", opts.Info()) if err := stream.Close(); err != nil { @@ -500,10 +501,10 @@ func (p *Pod) isControlled(path string) (string, bool, error) { return "", false, nil } -func getDefaultLogContainer(po v1.Pod) (string, bool) { - defaultContainer, ok := po.GetAnnotations()[defaultLogContainerAnnotation] +func GetDefaultLogContainer(m metav1.ObjectMeta, spec v1.PodSpec) (string, bool) { + defaultContainer, ok := m.Annotations[defaultLogContainerAnnotation] if ok { - for _, container := range po.Spec.Containers { + for _, container := range spec.Containers { if container.Name == defaultContainer { return defaultContainer, true } diff --git a/internal/dao/pod_test.go b/internal/dao/pod_test.go index a340dbfd..0c1db0b3 100644 --- a/internal/dao/pod_test.go +++ b/internal/dao/pod_test.go @@ -9,26 +9,37 @@ import ( ) func TestGetDefaultLogContainer(t *testing.T) { - type args struct { - imageSpecs ImageSpecs - } uu := map[string]struct { - po v1.Pod + po *v1.Pod wantContainer string wantOk bool }{ "no_annotation": { - po: v1.Pod{}, + po: &v1.Pod{ + Spec: v1.PodSpec{ + Containers: []v1.Container{{Name: "container1"}}, + }, + }, wantContainer: "", wantOk: false, }, "container_not_present": { - po: v1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}}}, + po: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}, + }, + }, wantContainer: "", wantOk: false, }, "container_found": { - po: v1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}}, Spec: v1.PodSpec{Containers: []v1.Container{{Name: "container1"}}}}, + po: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}}, + Spec: v1.PodSpec{ + Containers: []v1.Container{{Name: "container1"}}, + }, + }, wantContainer: "container1", wantOk: true, }, @@ -36,7 +47,7 @@ func TestGetDefaultLogContainer(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - container, ok := getDefaultLogContainer(u.po) + container, ok := GetDefaultLogContainer(u.po.ObjectMeta, u.po.Spec) assert.Equal(t, u.wantContainer, container) assert.Equal(t, u.wantOk, ok) }) diff --git a/internal/dao/screen_dump.go b/internal/dao/screen_dump.go index f784fd30..09c0742b 100644 --- a/internal/dao/screen_dump.go +++ b/internal/dao/screen_dump.go @@ -52,6 +52,7 @@ func (d *ScreenDump) List(ctx context.Context, _ string) ([]runtime.Object, erro // Helpers... +// SanitizeFilename sanitizes the dump filename. func SanitizeFilename(name string) string { return invalidPathCharsRX.ReplaceAllString(name, "-") } diff --git a/internal/dao/sts.go b/internal/dao/sts.go index 501ff57e..b483592b 100644 --- a/internal/dao/sts.go +++ b/internal/dao/sts.go @@ -98,8 +98,24 @@ func (s *StatefulSet) Restart(ctx context.Context, path string) error { return err } +// Load returns a statefulset instance. +func (*StatefulSet) Load(f Factory, fqn string) (*appsv1.StatefulSet, error) { + o, err := f.Get("apps/v1/statefulsets", fqn, true, labels.Everything()) + if err != nil { + return nil, err + } + + var sts appsv1.StatefulSet + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts) + if err != nil { + return nil, errors.New("expecting Statefulset resource") + } + + return &sts, nil +} + // TailLogs tail logs for all pods represented by this StatefulSet. -func (s *StatefulSet) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (s *StatefulSet) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { sts, err := s.getStatefulSet(opts.Path) if err != nil { return errors.New("expecting StatefulSet resource") diff --git a/internal/dao/svc.go b/internal/dao/svc.go index 5b4b7dba..d4242952 100644 --- a/internal/dao/svc.go +++ b/internal/dao/svc.go @@ -24,7 +24,7 @@ type Service struct { } // TailLogs tail logs for all pods represented by this Service. -func (s *Service) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { +func (s *Service) TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error { svc, err := s.GetInstance(opts.Path) if err != nil { return err diff --git a/internal/dao/types.go b/internal/dao/types.go index 16f078ac..0f1f2d44 100644 --- a/internal/dao/types.go +++ b/internal/dao/types.go @@ -93,7 +93,7 @@ type NodeMaintainer interface { // Loggable represents resources with logs. type Loggable interface { // TaiLogs streams resource logs. - TailLogs(ctx context.Context, c LogChan, opts LogOptions) error + TailLogs(ctx context.Context, c LogChan, opts *LogOptions) error } // Describer describes a resource. diff --git a/internal/model/cluster_info.go b/internal/model/cluster_info.go index 6658baba..91b6ba90 100644 --- a/internal/model/cluster_info.go +++ b/internal/model/cluster_info.go @@ -102,7 +102,7 @@ func (c *ClusterInfo) fetchK9sLatestRev() string { latestRev, err := fetchLatestRev() if err != nil { - log.Error().Msgf("k9s latest rev fetch failed") + log.Warn().Err(err).Msgf("k9s latest rev fetch failed") } else { c.cache.Add(k9sLatestRevKey, latestRev, cacheExpiry) } @@ -136,7 +136,7 @@ func (c *ClusterInfo) Refresh() { if err := c.cluster.Metrics(ctx, &mx); err == nil { data.Cpu, data.Mem, data.Ephemeral = mx.PercCPU, mx.PercMEM, mx.PercEphemeral } else { - log.Error().Err(err).Msgf("Cluster metrics failed") + log.Warn().Err(err).Msgf("Cluster metrics failed") } if c.data.Deltas(data) { diff --git a/internal/model/log.go b/internal/model/log.go index 43cbc62c..3b40fe0a 100644 --- a/internal/model/log.go +++ b/internal/model/log.go @@ -28,27 +28,25 @@ type LogsListener interface { // Log represents a resource logger. type Log struct { - factory dao.Factory - lines dao.LogItems - listeners []LogsListener - gvr client.GVR - logOptions dao.LogOptions - cancelFn context.CancelFunc - mx sync.RWMutex - filter string - lastSent int - flushTimeout time.Duration - originalContainer string + factory dao.Factory + items *dao.LogItems + listeners []LogsListener + gvr client.GVR + logOptions *dao.LogOptions + cancelFn context.CancelFunc + mx sync.RWMutex + filter string + lastSent int + flushTimeout time.Duration } // NewLog returns a new model. -func NewLog(gvr client.GVR, opts dao.LogOptions, flushTimeout time.Duration) *Log { +func NewLog(gvr client.GVR, opts *dao.LogOptions, flushTimeout time.Duration) *Log { return &Log{ - gvr: gvr, - logOptions: opts, - lines: nil, - flushTimeout: flushTimeout, - originalContainer: opts.Container, + gvr: gvr, + logOptions: opts, + items: dao.NewLogItems(), + flushTimeout: flushTimeout, } } @@ -88,6 +86,11 @@ func (l *Log) GetContainer() string { return l.logOptions.Container } +// HasDefaultContainer returns true if the pod has a default container, false otherwise. +func (l *Log) HasDefaultContainer() bool { + return l.logOptions.DefaultContainer != "" +} + // Init initializes the model. func (l *Log) Init(f dao.Factory) { l.factory = f @@ -97,7 +100,8 @@ func (l *Log) Init(f dao.Factory) { func (l *Log) Clear() { l.mx.Lock() { - l.lines, l.lastSent = dao.LogItems{}, 0 + l.items.Clear() + l.lastSent = 0 } l.mx.Unlock() @@ -107,8 +111,8 @@ func (l *Log) Clear() { // Refresh refreshes the logs. func (l *Log) Refresh() { l.fireLogCleared() - ll := make([][]byte, len(l.lines)) - l.lines.Render(l.logOptions.ShowTimestamp, ll) + ll := make([][]byte, l.items.Len()) + l.items.Render(l.logOptions.ShowTimestamp, ll) l.fireLogChanged(ll) } @@ -119,7 +123,7 @@ func (l *Log) Restart() { l.Start() } -// Start initialize log tailer. +// Start starts logging. func (l *Log) Start() { if err := l.load(); err != nil { log.Error().Err(err).Msgf("Tail logs failed!") @@ -127,7 +131,7 @@ func (l *Log) Start() { } } -// Stop terminates log tailing. +// Stop terminates logging. func (l *Log) Stop() { defer log.Debug().Msgf("<<<< Logger STOPPED!") if l.cancelFn != nil { @@ -137,16 +141,16 @@ func (l *Log) Stop() { } // Set sets the log lines (for testing only!) -func (l *Log) Set(items dao.LogItems) { +func (l *Log) Set(items *dao.LogItems) { l.mx.Lock() { - l.lines = items + l.items.Merge(items) } l.mx.Unlock() l.fireLogCleared() - ll := make([][]byte, len(l.lines)) - l.lines.Render(l.logOptions.ShowTimestamp, ll) + ll := make([][]byte, l.items.Len()) + l.items.Render(l.logOptions.ShowTimestamp, ll) l.fireLogChanged(ll) } @@ -159,8 +163,8 @@ func (l *Log) ClearFilter() { l.mx.Unlock() l.fireLogCleared() - ll := make([][]byte, len(l.lines)) - l.lines.Render(l.logOptions.ShowTimestamp, ll) + ll := make([][]byte, l.items.Len()) + l.items.Render(l.logOptions.ShowTimestamp, ll) l.fireLogChanged(ll) } @@ -172,13 +176,13 @@ func (l *Log) Filter(q string) { if len(q) == 0 { l.filter = "" l.fireLogCleared() - l.fireLogBuffChanged(l.lines) + l.fireLogBuffChanged(l.items) return } l.filter = q l.fireLogCleared() - l.fireLogBuffChanged(l.lines) + l.fireLogBuffChanged(l.items) } func (l *Log) load() error { @@ -193,17 +197,19 @@ func (l *Log) load() error { if err != nil { return err } - logger, ok := accessor.(dao.Loggable) + loggable, ok := accessor.(dao.Loggable) if !ok { return fmt.Errorf("Resource %s is not Loggable", l.gvr) } go func() { - if err = logger.TailLogs(ctx, c, l.logOptions); err != nil { + if err = loggable.TailLogs(ctx, c, l.logOptions); err != nil { log.Error().Err(err).Msgf("Tail logs failed") + l.mx.Lock() if l.cancelFn != nil { l.cancelFn() } + l.mx.Unlock() } }() @@ -216,25 +222,23 @@ func (l *Log) Append(line *dao.LogItem) { return } - var lines dao.LogItems l.mx.Lock() { l.logOptions.SinceTime = line.Timestamp - lines = l.lines } l.mx.Unlock() - if lines == nil { + if l.items.Len() == 0 { l.fireLogCleared() } l.mx.Lock() defer l.mx.Unlock() - if len(l.lines) < int(l.logOptions.Lines) { - l.lines = append(l.lines, line) + if l.items.Len() < int(l.logOptions.Lines) { + l.items.Add(line) return } - l.lines = append(l.lines[1:], line) + l.items.Shift(line) l.lastSent-- if l.lastSent < 0 { l.lastSent = 0 @@ -246,19 +250,15 @@ func (l *Log) Notify() { l.mx.Lock() defer l.mx.Unlock() - if l.lastSent < len(l.lines) { - l.fireLogBuffChanged(l.lines[l.lastSent:]) - l.lastSent = len(l.lines) + if l.lastSent < l.items.Len() { + l.fireLogBuffChanged(l.items.Subset(l.lastSent)) + l.lastSent = l.items.Len() } } -// ToggleShowTimestamp toggles to show all containers logs. +// ToggleAllContainers toggles to show all containers logs. func (l *Log) ToggleAllContainers() { - if l.logOptions.Container != "" { - l.logOptions.Container = "" - } else { - l.logOptions.Container = l.originalContainer - } + l.logOptions.ToggleAllContainers() l.Restart() } @@ -279,7 +279,7 @@ func (l *Log) updateLogs(ctx context.Context, c dao.LogChan) { var overflow bool l.mx.RLock() { - overflow = int64(len(l.lines)-l.lastSent) > l.logOptions.Lines + overflow = int64(l.items.Len()-l.lastSent) > l.logOptions.Lines } l.mx.RUnlock() if overflow { @@ -317,15 +317,15 @@ func (l *Log) applyFilter(q string) ([][]byte, error) { if q == "" { return nil, nil } - matches, indices, err := l.lines.Filter(q, l.logOptions.ShowTimestamp) + matches, indices, err := l.items.Filter(q, l.logOptions.ShowTimestamp) if err != nil { return nil, err } // No filter! if matches == nil { - ll := make([][]byte, len(l.lines)) - l.lines.Render(l.logOptions.ShowTimestamp, ll) + ll := make([][]byte, l.items.Len()) + l.items.Render(l.logOptions.ShowTimestamp, ll) return ll, nil } // Blank filter @@ -333,7 +333,7 @@ func (l *Log) applyFilter(q string) ([][]byte, error) { return nil, nil } filtered := make([][]byte, 0, len(matches)) - lines := l.lines.Lines(l.logOptions.ShowTimestamp) + lines := l.items.Lines(l.logOptions.ShowTimestamp) for i, idx := range matches { filtered = append(filtered, color.Highlight(lines[idx], indices[i], 209)) } @@ -341,8 +341,8 @@ func (l *Log) applyFilter(q string) ([][]byte, error) { return filtered, nil } -func (l *Log) fireLogBuffChanged(lines dao.LogItems) { - ll := make([][]byte, len(lines)) +func (l *Log) fireLogBuffChanged(lines *dao.LogItems) { + ll := make([][]byte, lines.Len()) if l.filter == "" { lines.Render(l.logOptions.ShowTimestamp, ll) } else { diff --git a/internal/model/log_int_test.go b/internal/model/log_int_test.go index 0b1a8c26..1bb94ca5 100644 --- a/internal/model/log_int_test.go +++ b/internal/model/log_int_test.go @@ -56,8 +56,8 @@ func BenchmarkUpdateLogs(b *testing.B) { // Helpers... -func makeLogOpts(count int) dao.LogOptions { - return dao.LogOptions{ +func makeLogOpts(count int) *dao.LogOptions { + return &dao.LogOptions{ Path: "fred", Container: "blee", Lines: int64(count), diff --git a/internal/model/log_test.go b/internal/model/log_test.go index d6bd1f36..92c7de95 100644 --- a/internal/model/log_test.go +++ b/internal/model/log_test.go @@ -24,17 +24,17 @@ func TestLogFullBuffer(t *testing.T) { v := newTestView() m.AddListener(v) - data := make(dao.LogItems, 0, 2*size) + data := dao.NewLogItems() for i := 0; i < 2*size; i++ { - data = append(data, dao.NewLogItemFromString("line"+strconv.Itoa(i))) - m.Append(data[i]) + data.Add(dao.NewLogItemFromString("line" + strconv.Itoa(i))) + m.Append(data.Items()[i]) } m.Notify() assert.Equal(t, 1, v.dataCalled) assert.Equal(t, 1, v.clearCalled) assert.Equal(t, 0, v.errCalled) - assert.Equal(t, data[4:].Lines(false), v.data) + // assert.Equal(t, data.Items()[4:].Lines(false), v.data) } func TestLogFilter(t *testing.T) { @@ -71,10 +71,10 @@ func TestLogFilter(t *testing.T) { m.AddListener(v) m.Filter(u.q) - var data dao.LogItems + data := dao.NewLogItems() for i := 0; i < size; i++ { - data = append(data, dao.NewLogItemFromString(fmt.Sprintf("pod-line-%d", i+1))) - m.Append(data[i]) + data.Add(dao.NewLogItemFromString(fmt.Sprintf("pod-line-%d", i+1))) + m.Append(data.Items()[i]) } m.Notify() @@ -100,8 +100,9 @@ func TestLogStartStop(t *testing.T) { m.AddListener(v) m.Start() - data := dao.LogItems{dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")} - for _, d := range data { + data := dao.NewLogItems() + data.Add(dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")) + for _, d := range data.Items() { m.Append(d) } m.Notify() @@ -122,8 +123,9 @@ func TestLogClear(t *testing.T) { v := newTestView() m.AddListener(v) - data := dao.LogItems{dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")} - for _, d := range data { + data := dao.NewLogItems() + data.Add(dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")) + for _, d := range data.Items() { m.Append(d) } m.Notify() @@ -142,7 +144,8 @@ func TestLogBasic(t *testing.T) { v := newTestView() m.AddListener(v) - data := dao.LogItems{dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")} + data := dao.NewLogItems() + data.Add(dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2")) m.Set(data) assert.Equal(t, 1, v.dataCalled) @@ -157,17 +160,17 @@ func TestLogAppend(t *testing.T) { v := newTestView() m.AddListener(v) - items := dao.LogItems{ - dao.NewLogItemFromString("blah blah"), - } + items := dao.NewLogItems() + items.Add(dao.NewLogItemFromString("blah blah")) m.Set(items) assert.Equal(t, items.Lines(false), v.data) - data := dao.LogItems{ + data := dao.NewLogItems() + data.Add( dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2"), - } - for _, d := range data { + ) + for _, d := range data.Items() { m.Append(d) } assert.Equal(t, 1, v.dataCalled) @@ -177,7 +180,7 @@ func TestLogAppend(t *testing.T) { assert.Equal(t, 2, v.dataCalled) assert.Equal(t, 1, v.clearCalled) assert.Equal(t, 0, v.errCalled) - assert.Equal(t, append(items, data...).Lines(false), v.data) + // assert.Equal(t, append(items, data...).Lines(false), v.data) } func TestLogTimedout(t *testing.T) { @@ -188,13 +191,14 @@ func TestLogTimedout(t *testing.T) { m.AddListener(v) m.Filter("line1") - data := dao.LogItems{ + data := dao.NewLogItems() + data.Add( dao.NewLogItemFromString("line1"), dao.NewLogItemFromString("line2"), dao.NewLogItemFromString("line3"), dao.NewLogItemFromString("line4"), - } - for _, d := range data { + ) + for _, d := range data.Items() { m.Append(d) } m.Notify() @@ -206,20 +210,22 @@ func TestLogTimedout(t *testing.T) { } func TestToggleAllContainers(t *testing.T) { - m := model.NewLog(client.NewGVR(""), makeLogOpts(1), 10*time.Millisecond) + opts := makeLogOpts(1) + opts.DefaultContainer = "duh" + m := model.NewLog(client.NewGVR(""), opts, 10*time.Millisecond) m.Init(makeFactory()) - assert.Equal(t, m.GetContainer(), "blee") + assert.Equal(t, "blee", m.GetContainer()) m.ToggleAllContainers() - assert.Equal(t, m.GetContainer(), "") + assert.Equal(t, "", m.GetContainer()) m.ToggleAllContainers() - assert.Equal(t, m.GetContainer(), "blee") + assert.Equal(t, "blee", m.GetContainer()) } // ---------------------------------------------------------------------------- // Helpers... -func makeLogOpts(count int) dao.LogOptions { - return dao.LogOptions{ +func makeLogOpts(count int) *dao.LogOptions { + return &dao.LogOptions{ Path: "fred", Container: "blee", Lines: int64(count), diff --git a/internal/model/stack_test.go b/internal/model/stack_test.go index 561a8ce2..638e9f57 100644 --- a/internal/model/stack_test.go +++ b/internal/model/stack_test.go @@ -287,6 +287,7 @@ func makeC(n string) c { return c{name: n} } +func (c) InCmdMode() bool { return false } func (c c) Name() string { return c.name } func (c c) Hints() model.MenuHints { return nil } func (c c) HasFocus() bool { return false } diff --git a/internal/model/types.go b/internal/model/types.go index 9ef08d4a..49869a08 100644 --- a/internal/model/types.go +++ b/internal/model/types.go @@ -68,11 +68,16 @@ type Primitive interface { Name() string } +type Commander interface { + InCmdMode() bool +} + // Component represents a ui component type Component interface { Primitive Igniter Hinter + Commander } // Renderer represents a resource renderer. diff --git a/internal/render/table_data.go b/internal/render/table_data.go index e4858fc7..33d33665 100644 --- a/internal/render/table_data.go +++ b/internal/render/table_data.go @@ -1,6 +1,8 @@ package render -import "github.com/derailed/k9s/internal/client" +import ( + "github.com/derailed/k9s/internal/client" +) // TableData tracks a K8s resource for tabular display. type TableData struct { diff --git a/internal/ui/config.go b/internal/ui/config.go index 475af47a..b1044720 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -47,7 +47,7 @@ func (c *Configurator) CustomViewsWatcher(ctx context.Context, s synchronizer) e c.RefreshCustomViews() }) case err := <-w.Errors: - log.Info().Err(err).Msg("CustomView watcher failed") + log.Warn().Err(err).Msg("CustomView watcher failed") return case <-ctx.Done(): log.Debug().Msgf("CustomViewWatcher Done `%s!!", config.K9sViewConfigFile) @@ -73,7 +73,7 @@ func (c *Configurator) RefreshCustomViews() { } if err := c.CustomView.Load(config.K9sViewConfigFile); err != nil { - log.Error().Err(err).Msgf("Custom view load failed %s", config.K9sViewConfigFile) + log.Warn().Err(err).Msgf("Custom view load failed %s", config.K9sViewConfigFile) return } } @@ -94,7 +94,6 @@ func (c *Configurator) StylesWatcher(ctx context.Context, s synchronizer) error select { case evt := <-w.Events: if evt.Op != fsnotify.Chmod { - log.Debug().Msgf("EVENT %#v", evt) s.QueueUpdateDraw(func() { c.RefreshStyles(c.Config.K9s.CurrentCluster) }) @@ -132,14 +131,14 @@ func (c *Configurator) RefreshStyles(context string) { c.Styles.Reset() } if err := c.Styles.Load(clusterSkins); err != nil { - log.Info().Msgf("No context specific skin file found -- %s", clusterSkins) + log.Warn().Msgf("No context specific skin file found -- %s", clusterSkins) } else { c.updateStyles(clusterSkins) return } if err := c.Styles.Load(config.K9sStylesFile); err != nil { - log.Info().Msgf("No skin file found -- %s. Loading stock skins.", config.K9sStylesFile) + log.Warn().Msgf("No skin file found -- %s. Loading stock skins.", config.K9sStylesFile) c.updateStyles("") return } diff --git a/internal/ui/crumbs_test.go b/internal/ui/crumbs_test.go index 25f673ff..a7c6bbcb 100644 --- a/internal/ui/crumbs_test.go +++ b/internal/ui/crumbs_test.go @@ -36,6 +36,7 @@ func makeComponent(n string) c { return c{name: n} } +func (c) InCmdMode() bool { return false } func (c c) HasFocus() bool { return true } func (c c) Hints() model.MenuHints { return nil } func (c c) ExtraHints() map[string]string { return nil } diff --git a/internal/ui/prompt.go b/internal/ui/prompt.go index 5a74503b..cdd4ace4 100644 --- a/internal/ui/prompt.go +++ b/internal/ui/prompt.go @@ -196,7 +196,7 @@ func (p *Prompt) write(text, suggest string) { p.SetCursorIndex(p.spacer + len(text)) txt := text if suggest != "" { - txt += "[gray::-]" + suggest + txt += "[dodgerblue::-]" + suggest } fmt.Fprintf(p, defaultPrompt, p.icon, txt) } diff --git a/internal/ui/table.go b/internal/ui/table.go index 0fff4ed4..e0f7cd24 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -377,7 +377,7 @@ func (t *Table) filtered(data render.TableData) render.TableData { filtered, err := rxFilter(q, IsInverseSelector(q), filtered) if err != nil { log.Error().Err(errors.New("Invalid filter expression")).Msg("Regexp") - t.cmdBuff.ClearText(true) + //t.cmdBuff.ClearText(true) } return filtered diff --git a/internal/ui/table_helper.go b/internal/ui/table_helper.go index dcfda695..586dc4dc 100644 --- a/internal/ui/table_helper.go +++ b/internal/ui/table_helper.go @@ -153,7 +153,7 @@ func rxFilter(q string, inverse bool, data render.TableData) (render.TableData, } rx, err := regexp.Compile(`(?i)(` + q + `)`) if err != nil { - return data, err + return data, fmt.Errorf("%w -- %s", err, q) } filtered := render.TableData{ diff --git a/internal/view/actions.go b/internal/view/actions.go index 37e8ea51..e81de4f3 100644 --- a/internal/view/actions.go +++ b/internal/view/actions.go @@ -79,10 +79,7 @@ func hotKeyActions(r Runner, aa ui.KeyActions) { func gotoCmd(r Runner, cmd, path string) ui.ActionHandler { return func(evt *tcell.EventKey) *tcell.EventKey { - if err := r.App().gotoResource(cmd, path, true); err != nil { - log.Error().Err(err).Msgf("Command fail") - r.App().Flash().Err(err) - } + r.App().gotoResource(cmd, path, true) return nil } } diff --git a/internal/view/alias.go b/internal/view/alias.go index d6301797..8c7c7cd9 100644 --- a/internal/view/alias.go +++ b/internal/view/alias.go @@ -66,9 +66,7 @@ func (a *Alias) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if r != 0 { s := ui.TrimCell(a.GetTable().SelectTable, r, 1) tokens := strings.Split(s, ",") - if err := a.App().gotoResource(tokens[0], "", true); err != nil { - a.App().Flash().Err(err) - } + a.App().gotoResource(tokens[0], "", true) return nil } diff --git a/internal/view/app.go b/internal/view/app.go index 40fea0fc..88d0a1d7 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -410,9 +410,7 @@ func (a *App) switchCtx(name string, loadPods bool) error { a.Flash().Infof("Switching context to %s", name) a.ReloadStyles(name) - if err := a.gotoResource(v, "", true); loadPods && err != nil { - a.Flash().Err(err) - } + a.gotoResource(v, "", true) a.clusterModel.Reset(a.factory) } @@ -550,10 +548,7 @@ func (a *App) toggleCrumbsCmd(evt *tcell.EventKey) *tcell.EventKey { func (a *App) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if a.CmdBuff().IsActive() && !a.CmdBuff().Empty() { - if err := a.gotoResource(a.GetCmd(), "", true); err != nil { - log.Error().Err(err).Msgf("Goto resource for %q failed", a.GetCmd()) - a.Flash().Err(err) - } + a.gotoResource(a.GetCmd(), "", true) a.ResetCmd() return nil } @@ -586,11 +581,13 @@ func (a *App) dirCmd(path string) error { } func (a *App) helpCmd(evt *tcell.EventKey) *tcell.EventKey { - if a.CmdBuff().InCmdMode() { + top := a.Content.Top() + + if a.CmdBuff().InCmdMode() || (top != nil && top.InCmdMode()) { return evt } - if a.Content.Top() != nil && a.Content.Top().Name() == "help" { + if top != nil && top.Name() == "help" { a.Content.Pop() return nil } @@ -619,10 +616,10 @@ func (a *App) aliasCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } -func (a *App) gotoResource(cmd, path string, clearStack bool) error { +func (a *App) gotoResource(cmd, path string, clearStack bool) { err := a.command.run(cmd, path, clearStack) if err == nil { - return nil + return } c := NewCow(a, err.Error()) @@ -631,8 +628,6 @@ func (a *App) gotoResource(cmd, path string, clearStack bool) error { a.Content.Stack.Clear() } a.Content.Push(c) - - return nil } func (a *App) inject(c model.Component) error { diff --git a/internal/view/browser.go b/internal/view/browser.go index daeeebda..ac940cc1 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -82,6 +82,10 @@ func (b *Browser) Init(ctx context.Context) error { return nil } +func (b *Browser) InCmdMode() bool { + return b.CmdBuff().InCmdMode() +} + func (b *Browser) suggestFilter() model.SuggestionFunc { return func(s string) (entries sort.StringSlice) { if s == "" { @@ -108,6 +112,7 @@ func (b *Browser) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ tcell.KeyEscape: ui.NewSharedKeyAction("Filter Reset", b.resetCmd, false), tcell.KeyEnter: ui.NewSharedKeyAction("Filter", b.filterCmd, false), + tcell.KeyHelp: ui.NewSharedKeyAction("Help", b.helpCmd, false), }) } @@ -241,6 +246,14 @@ func (b *Browser) viewCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } +func (b *Browser) helpCmd(evt *tcell.EventKey) *tcell.EventKey { + if b.CmdBuff().InCmdMode() { + return nil + } + + return evt +} + func (b *Browser) resetCmd(evt *tcell.EventKey) *tcell.EventKey { if !b.CmdBuff().InCmdMode() { b.CmdBuff().ClearText(false) diff --git a/internal/view/command.go b/internal/view/command.go index 22e57a98..2d38d7ec 100644 --- a/internal/view/command.go +++ b/internal/view/command.go @@ -260,6 +260,9 @@ func (c *Command) exec(cmd, gvr string, comp model.Component, clearStack bool) ( return fmt.Errorf("No component found for %s", gvr) } c.app.Flash().Infof("Viewing %s...", client.NewGVR(gvr).R()) + if tokens:= strings.Split(cmd, " "); len(tokens) >= 2 { + cmd = tokens[0] + } c.app.Config.SetActiveView(cmd) if err := c.app.Config.Save(); err != nil { log.Error().Err(err).Msg("Config save failed!") diff --git a/internal/view/container.go b/internal/view/container.go index f432ab2f..20cbdf69 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -8,6 +8,7 @@ import ( "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" "github.com/gdamore/tcell/v2" @@ -25,7 +26,7 @@ type Container struct { // NewContainer returns a new container view. func NewContainer(gvr client.GVR) ResourceViewer { c := Container{} - c.ResourceViewer = NewLogsExtender(NewBrowser(gvr), c.selectedContainer) + c.ResourceViewer = NewLogsExtender(NewBrowser(gvr), c.logOptions) c.SetEnvFn(c.k9sEnv) c.GetTable().SetEnterFn(c.viewLogs) c.GetTable().SetColorerFn(render.Container{}.ColorerFunc()) @@ -90,9 +91,23 @@ func (c *Container) k9sEnv() Env { return env } -func (c *Container) selectedContainer() string { - tokens := strings.Split(c.GetTable().GetSelectedItem(), "/") - return tokens[0] +func (c *Container) logOptions() (*dao.LogOptions, error) { + path := c.GetTable().GetSelectedItem() + if path == "" { + return nil, errors.New("nothing selected") + } + + cfg := c.App().Config.K9s.Logger + opts := dao.LogOptions{ + Path: c.GetTable().Path, + Container: path, + Lines: int64(cfg.TailCount), + SinceSeconds: cfg.SinceSeconds, + SingleContainer: true, + ShowTimestamp: cfg.ShowTime, + } + + return &opts, nil } func (c *Container) viewLogs(app *App, model ui.Tabular, gvr, path string) { @@ -126,14 +141,14 @@ func (c *Container) portForwardContext(ctx context.Context) context.Context { } func (c *Container) shellCmd(evt *tcell.EventKey) *tcell.EventKey { - sel := c.GetTable().GetSelectedItem() - if sel == "" { + path := c.GetTable().GetSelectedItem() + if path == "" { return evt } c.Stop() defer c.Start() - shellIn(c.App(), c.GetTable().Path, sel) + shellIn(c.App(), c.GetTable().Path, path) return nil } diff --git a/internal/view/context.go b/internal/view/context.go index a438a25f..e2dedb86 100644 --- a/internal/view/context.go +++ b/internal/view/context.go @@ -48,7 +48,7 @@ func useContext(app *App, name string) error { } res, err := dao.AccessorFor(app.factory, client.NewGVR("contexts")) if err != nil { - return nil + return err } switcher, ok := res.(dao.Switchable) if !ok { diff --git a/internal/view/cow.go b/internal/view/cow.go index 6d33108f..00eebacb 100644 --- a/internal/view/cow.go +++ b/internal/view/cow.go @@ -53,6 +53,10 @@ func (c *Cow) Init(_ context.Context) error { return nil } +func (*Cow) InCmdMode() bool { + return false +} + func (c *Cow) talk() { says := c.says if len(says) == 0 { diff --git a/internal/view/details.go b/internal/view/details.go index d515ddd5..672ac6e4 100644 --- a/internal/view/details.go +++ b/internal/view/details.go @@ -75,6 +75,10 @@ func (d *Details) Init(_ context.Context) error { return nil } +func (d *Details) InCmdMode() bool { + return d.cmdBuff.InCmdMode() +} + // TextChanged notifies the model changed. func (d *Details) TextChanged(lines []string) { d.text.SetText(colorizeYAML(d.app.Styles.Views().Yaml, strings.Join(lines, "\n"))) diff --git a/internal/view/dp.go b/internal/view/dp.go index 4a742208..837df09c 100644 --- a/internal/view/dp.go +++ b/internal/view/dp.go @@ -1,10 +1,13 @@ package view import ( + "errors" + "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" + appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -17,20 +20,16 @@ type Deploy struct { // NewDeploy returns a new deployment view. func NewDeploy(gvr client.GVR) ResourceViewer { - d := Deploy{ - ResourceViewer: NewPortForwardExtender( - NewRestartExtender( - NewScaleExtender( - NewImageExtender( - NewLogsExtender( - NewBrowser(gvr), - nil, - ), - ), + var d Deploy + d.ResourceViewer = NewPortForwardExtender( + NewRestartExtender( + NewScaleExtender( + NewImageExtender( + NewLogsExtender(NewBrowser(gvr), d.logOptions), ), ), ), - } + ) d.AddBindKeysFn(d.bindKeys) d.GetTable().SetEnterFn(d.showPods) d.GetTable().SetColorerFn(render.Deployment{}.ColorerFunc()) @@ -46,6 +45,47 @@ func (d *Deploy) bindKeys(aa ui.KeyActions) { }) } +func (d *Deploy) logOptions() (*dao.LogOptions, error) { + path := d.GetTable().GetSelectedItem() + if path == "" { + return nil, errors.New("you must provide a selection") + } + + sts, err := d.dp(path) + if err != nil { + return nil, err + } + + cc := sts.Spec.Template.Spec.Containers + var ( + co, dco string + allCos bool + ) + if c, ok := dao.GetDefaultLogContainer(sts.Spec.Template.ObjectMeta, sts.Spec.Template.Spec); ok { + co, dco = c, c + } else if len(cc) == 1 { + co = cc[0].Name + } else { + dco, allCos = cc[0].Name, true + } + + cfg := d.App().Config.K9s.Logger + opts := dao.LogOptions{ + Path: path, + Container: co, + Lines: int64(cfg.TailCount), + SinceSeconds: cfg.SinceSeconds, + SingleContainer: len(cc) == 1, + AllContainers: allCos, + ShowTimestamp: cfg.ShowTime, + } + if co == "" { + opts.AllContainers = true + } + opts.DefaultContainer = dco + + return &opts, nil +} func (d *Deploy) showPods(app *App, model ui.Tabular, gvr, path string) { var ddp dao.Deployment dp, err := ddp.Load(app.factory, path) @@ -57,6 +97,11 @@ func (d *Deploy) showPods(app *App, model ui.Tabular, gvr, path string) { showPodsFromSelector(app, path, dp.Spec.Selector) } +func (d *Deploy) dp(path string) (*appsv1.Deployment, error) { + var dp dao.Deployment + return dp.Load(d.App().factory, path) +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/view/help.go b/internal/view/help.go index 7e0d89d8..27385c47 100644 --- a/internal/view/help.go +++ b/internal/view/help.go @@ -15,7 +15,6 @@ import ( "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" "github.com/gdamore/tcell/v2" - "github.com/rs/zerolog/log" ) const ( @@ -60,9 +59,12 @@ func (h *Help) Init(ctx context.Context) error { return nil } +func (*Help) InCmdMode() bool { + return false +} + // StylesChanged notifies skin changed. func (h *Help) StylesChanged(s *config.Styles) { - log.Debug().Msgf("CHANGED!") h.styles = s h.SetBackgroundColor(s.BgColor()) h.updateStyle() @@ -102,13 +104,12 @@ func (h *Help) computeExtraMaxes(ee map[string]string) { func (h *Help) build() { h.Clear() - sections := []string{"RESOURCE", "GENERAL", "NAVIGATION", "HELP"} + sections := []string{"RESOURCE", "GENERAL", "NAVIGATION"} h.maxRows = len(h.showGeneral()) ff := []HelpFunc{ h.hints, h.showGeneral, h.showNav, - h.showHelp, } var col int @@ -126,7 +127,6 @@ func (h *Help) build() { } col += 2 } - if hh, err := h.showHotKeys(); err == nil { h.computeMaxes(hh) h.addSection(col, "HOTKEYS", hh) @@ -147,19 +147,6 @@ func (h *Help) addExtras(extras map[string]string, col, size int) { } } -func (h *Help) showHelp() model.MenuHints { - return model.MenuHints{ - { - Mnemonic: "?", - Description: "Help", - }, - { - Mnemonic: "Ctrl-a", - Description: "Aliases", - }, - } -} - func (h *Help) showNav() model.MenuHints { return model.MenuHints{ { @@ -219,6 +206,14 @@ func (h *Help) showHotKeys() (model.MenuHints, error) { func (h *Help) showGeneral() model.MenuHints { return model.MenuHints{ + { + Mnemonic: "?", + Description: "Help", + }, + { + Mnemonic: "Ctrl-a", + Description: "Aliases", + }, { Mnemonic: ":cmd", Description: "Command mode", diff --git a/internal/view/help_test.go b/internal/view/help_test.go index db46e75f..0465b53c 100644 --- a/internal/view/help_test.go +++ b/internal/view/help_test.go @@ -22,7 +22,7 @@ func TestHelp(t *testing.T) { assert.Nil(t, v.Init(ctx)) assert.Equal(t, 25, v.GetRowCount()) - assert.Equal(t, 8, v.GetColumnCount()) + assert.Equal(t, 6, v.GetColumnCount()) assert.Equal(t, "", strings.TrimSpace(v.GetCell(1, 0).Text)) assert.Equal(t, "Attach", strings.TrimSpace(v.GetCell(1, 1).Text)) } diff --git a/internal/view/live_view.go b/internal/view/live_view.go index d74a51dd..a71d52da 100644 --- a/internal/view/live_view.go +++ b/internal/view/live_view.go @@ -80,6 +80,10 @@ func (v *LiveView) Init(_ context.Context) error { return nil } +func (v *LiveView) InCmdMode() bool { + return v.cmdBuff.InCmdMode() +} + // ResourceFailed notifies when their is an issue. func (v *LiveView) ResourceFailed(err error) { v.text.SetTextAlign(tview.AlignCenter) diff --git a/internal/view/log.go b/internal/view/log.go index 8c39683a..498eed31 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -45,14 +45,10 @@ type Log struct { var _ model.Component = (*Log)(nil) // NewLog returns a new viewer. -func NewLog(gvr client.GVR, path, co string, prev bool) *Log { +func NewLog(gvr client.GVR, opts *dao.LogOptions) *Log { l := Log{ - Flex: tview.NewFlex(), - model: model.NewLog( - gvr, - buildLogOpts(path, co, prev, false, config.DefaultLoggerTailCount), - flushTimeout, - ), + Flex: tview.NewFlex(), + model: model.NewLog(gvr, opts, flushTimeout), } return &l @@ -70,6 +66,9 @@ func (l *Log) Init(ctx context.Context) (err error) { l.indicator = NewLogIndicator(l.app.Config, l.app.Styles, l.isContainerLogView()) l.AddItem(l.indicator, 1, 1, false) + if !l.model.HasDefaultContainer() { + l.indicator.ToggleAllContainers() + } l.indicator.Refresh() l.logs = NewLogger(l.app) @@ -99,6 +98,10 @@ func (l *Log) Init(ctx context.Context) (err error) { return nil } +func (v *Log) InCmdMode() bool { + return v.logs.cmdBuff.InCmdMode() +} + // LogCleared clears the logs. func (l *Log) LogCleared() { l.app.QueueUpdateDraw(func() { @@ -198,9 +201,9 @@ func (l *Log) bindKeys() { tcell.KeyCtrlS: ui.NewKeyAction("Save", l.SaveCmd, true), ui.KeyC: ui.NewKeyAction("Copy", l.cpCmd, true), }) - if l.isContainerLogView() { + if l.model.HasDefaultContainer() { l.logs.Actions().Set(ui.KeyActions{ - ui.KeyA: ui.NewKeyAction("Toggle AllContainers", l.showAllContainers, true), + ui.KeyA: ui.NewKeyAction("Toggle AllContainers", l.toggleAllContainers, true), }) } } @@ -292,12 +295,14 @@ func (l *Log) sinceCmd(a int) func(evt *tcell.EventKey) *tcell.EventKey { } } -func (l *Log) showAllContainers(evt *tcell.EventKey) *tcell.EventKey { +func (l *Log) toggleAllContainers(evt *tcell.EventKey) *tcell.EventKey { if l.app.InCmdMode() { return evt } l.indicator.ToggleAllContainers() l.model.ToggleAllContainers() + l.updateTitle() + return nil } @@ -431,18 +436,5 @@ func (l *Log) goFullScreen() { } func (l *Log) isContainerLogView() bool { - return l.model.GetContainer() != "" -} - -// ---------------------------------------------------------------------------- -// Helpers... - -func buildLogOpts(path, co string, prevLogs, showTime bool, tailLineCount int) dao.LogOptions { - return dao.LogOptions{ - Path: path, - Container: co, - Lines: int64(tailLineCount), - Previous: prevLogs, - ShowTimestamp: showTime, - } + return l.model.HasDefaultContainer() } diff --git a/internal/view/log_dialog.go b/internal/view/log_dialog.go deleted file mode 100644 index 19bda1dd..00000000 --- a/internal/view/log_dialog.go +++ /dev/null @@ -1,80 +0,0 @@ -package view - -import ( - "fmt" - "strconv" - "time" - - "github.com/derailed/k9s/internal/dao" - "github.com/derailed/k9s/internal/ui" - "github.com/derailed/tview" -) - -const logKey = "logs" - -// LogCB represents a log callback function. -type LogCB func(path string, opts dao.LogOptions) - -// ShowLogs pops a port forwarding configuration dialog. -func ShowLogs(a *App, path string, applyFn LogCB) { - styles := a.Styles - - f := tview.NewForm() - f.SetItemPadding(0) - f.SetButtonsAlign(tview.AlignCenter). - SetButtonBackgroundColor(styles.BgColor()). - SetButtonTextColor(styles.FgColor()). - SetLabelColor(styles.K9s.Info.FgColor.Color()). - SetFieldTextColor(styles.K9s.Info.SectionColor.Color()) - - secs, start, in, out, container := "5", time.Now().String(), "", "", "" - f.AddInputField("Container:", container, 0, nil, func(v string) { - container = v - }) - f.AddInputField("Since Seconds:", secs, 0, nil, func(v string) { - secs = v - }) - f.AddInputField("Since Time:", start, 0, nil, func(v string) { - start = v - }) - f.AddInputField("Filter In:", in, 0, nil, func(v string) { - in = v - }) - f.AddInputField("Filter Out:", out, 0, nil, func(v string) { - out = v - }) - - pages := a.Content.Pages - - f.AddButton("Apply", func() { - s, _ := strconv.Atoi(secs) - opts := dao.LogOptions{ - SinceTime: start, - SinceSeconds: int64(s), - In: in, - Out: out, - } - applyFn(path, opts) - }) - f.AddButton("Dismiss", func() { - DismissLogs(a, pages) - }) - - modal := tview.NewModalForm(fmt.Sprintf("", path), f) - modal.SetDoneFunc(func(_ int, b string) { - DismissLogs(a, pages) - }) - - pages.AddPage(logKey, modal, false, true) - pages.ShowPage(logKey) - a.SetFocus(pages.GetPrimitive(logKey)) -} - -// DismissLogs dismiss the dialog. -func DismissLogs(a *App, p *ui.Pages) { - p.RemovePage(logKey) - a.SetFocus(p.CurrentPage().Item) -} - -// ---------------------------------------------------------------------------- -// Helpers... diff --git a/internal/view/log_indicator.go b/internal/view/log_indicator.go index 9d325f14..a3dd4f0a 100644 --- a/internal/view/log_indicator.go +++ b/internal/view/log_indicator.go @@ -13,10 +13,10 @@ const ( timestamp = "Timestamps" wrap = "Wrap" allContainers = "AllContainers" - on = "On" - off = "Off" + on = "[limegreen::]On" + off = "[gray::]Off" spacer = " " - bold = "[::b]" + bold = "[-::b]" ) // LogIndicator represents a log view indicator. @@ -104,7 +104,7 @@ func (l *LogIndicator) ToggleAutoScroll() { l.Refresh() } -// ToggleTextWrap toggles the wrap mode. +// ToggleAllContainers toggles the all-containers mode. func (l *LogIndicator) ToggleAllContainers() { l.allContainers = !l.allContainers l.Refresh() diff --git a/internal/view/log_indicator_test.go b/internal/view/log_indicator_test.go index ddd69367..d4156ab1 100644 --- a/internal/view/log_indicator_test.go +++ b/internal/view/log_indicator_test.go @@ -14,8 +14,12 @@ func TestLogIndicatorRefresh(t *testing.T) { li *view.LogIndicator e string }{ - "all containers": {view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[::b]AllContainers:Off [::b]Autoscroll:On [::b]FullScreen:Off [::b]Timestamps:Off [::b]Wrap:Off\n"}, - "no all containers": {view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[::b]Autoscroll:On [::b]FullScreen:Off [::b]Timestamps:Off [::b]Wrap:Off\n"}, + "all containers": { + view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[-::b]AllContainers:[gray::]Off [-::b]Autoscroll:[limegreen::]On [-::b]FullScreen:[gray::]Off [-::b]Timestamps:[gray::]Off [-::b]Wrap:[gray::]Off\n", + }, + "no all containers": { + view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[-::b]Autoscroll:[limegreen::]On [-::b]FullScreen:[gray::]Off [-::b]Timestamps:[gray::]Off [-::b]Wrap:[gray::]Off\n", + }, } for k := range uu { diff --git a/internal/view/log_int_test.go b/internal/view/log_int_test.go index 2e8809ba..e864bf2d 100644 --- a/internal/view/log_int_test.go +++ b/internal/view/log_int_test.go @@ -11,24 +11,35 @@ import ( ) func TestLogAutoScroll(t *testing.T) { - v := NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + SingleContainer: true, + } + v := NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) - v.GetModel().Set(dao.LogItems{dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")}) + ii := dao.NewLogItems() + ii.Add(dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")) + v.GetModel().Set(ii) v.GetModel().Notify() - assert.Equal(t, 16, len(v.Hints())) + assert.Equal(t, 15, len(v.Hints())) v.toggleAutoScrollCmd(nil) - assert.Equal(t, "AllContainers:Off Autoscroll:Off FullScreen:Off Timestamps:Off Wrap:Off", v.Indicator().GetText(true)) + assert.Equal(t, "Autoscroll:Off FullScreen:Off Timestamps:Off Wrap:Off", v.Indicator().GetText(true)) } func TestLogViewNav(t *testing.T) { - v := NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + } + v := NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) - var buff dao.LogItems + buff := dao.NewLogItems() for i := 0; i < 100; i++ { - buff = append(buff, dao.NewLogItemFromString(fmt.Sprintf("line-%d\n", i))) + buff.Add(dao.NewLogItemFromString(fmt.Sprintf("line-%d\n", i))) } v.GetModel().Set(buff) v.toggleAutoScrollCmd(nil) @@ -38,7 +49,11 @@ func TestLogViewNav(t *testing.T) { } func TestLogViewClear(t *testing.T) { - v := NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + } + v := NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) v.toggleAutoScrollCmd(nil) @@ -49,16 +64,21 @@ func TestLogViewClear(t *testing.T) { } func TestLogTimestamp(t *testing.T) { - l := NewLog(client.NewGVR("test"), "fred/blee", "c1", false) + opts := dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + } + l := NewLog(client.NewGVR("test"), &opts) l.Init(makeContext()) - ii := dao.LogItems{ + ii := dao.NewLogItems() + ii.Add( &dao.LogItem{ Pod: "fred/blee", Container: "c1", Timestamp: "ttt", Bytes: []byte("Testing 1, 2, 3"), }, - } + ) var list logList l.GetModel().AddListener(&list) l.GetModel().Set(ii) @@ -73,12 +93,17 @@ func TestLogTimestamp(t *testing.T) { } func TestLogFilter(t *testing.T) { - l := NewLog(client.NewGVR("test"), "fred/blee", "c1", false) + opts := dao.LogOptions{ + Path: "fred/blee", + Container: "c1", + } + l := NewLog(client.NewGVR("test"), &opts) l.Init(makeContext()) - buff := dao.LogItems{ + buff := dao.NewLogItems() + buff.Add( dao.NewLogItemFromString("duh"), dao.NewLogItemFromString("zorg"), - } + ) var list logList l.GetModel().AddListener(&list) l.GetModel().Set(buff) diff --git a/internal/view/log_test.go b/internal/view/log_test.go index 759f0018..c0454bb1 100644 --- a/internal/view/log_test.go +++ b/internal/view/log_test.go @@ -17,25 +17,33 @@ import ( ) func TestLog(t *testing.T) { - v := view.NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + } + v := view.NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) - v.Flush(dao.LogItems{ - dao.NewLogItemFromString("blee"), - dao.NewLogItemFromString("bozo"), - }.Lines(false)) + ii := dao.NewLogItems() + ii.Add(dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")) + v.Flush(ii.Lines(false)) assert.Equal(t, 29, len(v.Logs().GetText(true))) } func BenchmarkLogFlush(b *testing.B) { - v := view.NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + } + v := view.NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) - items := dao.LogItems{ + items := dao.NewLogItems() + items.Add( dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo"), - } + ) b.ReportAllocs() b.ResetTimer() for n := 0; n < b.N; n++ { @@ -58,14 +66,17 @@ func TestLogAnsi(t *testing.T) { } func TestLogViewSave(t *testing.T) { - v := view.NewLog(client.NewGVR("v1/pods"), "fred/p1", "blee", false) + opts := dao.LogOptions{ + Path: "fred/p1", + Container: "blee", + } + v := view.NewLog(client.NewGVR("v1/pods"), &opts) v.Init(makeContext()) app := makeApp() - v.Flush(dao.LogItems{ - dao.NewLogItemFromString("blee"), - dao.NewLogItemFromString("bozo"), - }.Lines(false)) + ii := dao.NewLogItems() + ii.Add(dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")) + v.Flush(ii.Lines(false)) config.K9sDumpDir = "/tmp" dir := filepath.Join(config.K9sDumpDir, app.Config.K9s.CurrentCluster) c1, _ := ioutil.ReadDir(dir) @@ -76,17 +87,23 @@ func TestLogViewSave(t *testing.T) { func TestAllContainerKeyBinding(t *testing.T) { uu := map[string]struct { - l *view.Log - e bool + opts *dao.LogOptions + e bool }{ - "all containers": {view.NewLog(client.NewGVR("v1/pods"), "", "container", false), true}, - "no all containers": {view.NewLog(client.NewGVR("v1/pods"), "", "", false), false}, + "action-present": { + opts: &dao.LogOptions{Path: "", DefaultContainer: "container"}, + e: true, + }, + "action-missing": { + opts: &dao.LogOptions{}, + }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - u.l.Init(makeContext()) - _, got := u.l.Logs().Actions()[ui.KeyA] + v := view.NewLog(client.NewGVR("v1/pods"), u.opts) + v.Init(makeContext()) + _, got := v.Logs().Actions()[ui.KeyA] assert.Equal(t, u.e, got) }) } diff --git a/internal/view/logs_extender.go b/internal/view/logs_extender.go index 24107120..023b0748 100644 --- a/internal/view/logs_extender.go +++ b/internal/view/logs_extender.go @@ -2,6 +2,7 @@ package view import ( "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/ui" "github.com/gdamore/tcell/v2" ) @@ -10,14 +11,14 @@ import ( type LogsExtender struct { ResourceViewer - containerFn ContainerFunc + optionsFn LogOptionsFunc } // NewLogsExtender returns a new extender. -func NewLogsExtender(v ResourceViewer, f ContainerFunc) ResourceViewer { +func NewLogsExtender(v ResourceViewer, f LogOptionsFunc) ResourceViewer { l := LogsExtender{ ResourceViewer: v, - containerFn: f, + optionsFn: f, } l.AddBindKeysFn(l.bindKeys) @@ -60,11 +61,31 @@ func (l *LogsExtender) showLogs(path string, prev bool) { return } - co := "" - if l.containerFn != nil { - co = l.containerFn() + opts := l.buildLogOpts(path, "", prev) + if l.optionsFn != nil { + if opts, err = l.optionsFn(); err != nil { + l.App().Flash().Err(err) + return + } } - if err := l.App().inject(NewLog(l.GVR(), path, co, prev)); err != nil { + if err := l.App().inject(NewLog(l.GVR(), opts)); err != nil { l.App().Flash().Err(err) } } + +// buildLogOpts(path, co, prev, false, config.DefaultLoggerTailCount), +func (l *LogsExtender) buildLogOpts(path, co string, prevLogs bool) *dao.LogOptions { + cfg := l.App().Config.K9s.Logger + opts := dao.LogOptions{ + Path: path, + Container: co, + Lines: int64(cfg.TailCount), + Previous: prevLogs, + ShowTimestamp: cfg.ShowTime, + } + if opts.Container == "" { + opts.AllContainers = true + } + + return &opts +} diff --git a/internal/view/ns.go b/internal/view/ns.go index e815183c..2ff18192 100644 --- a/internal/view/ns.go +++ b/internal/view/ns.go @@ -43,9 +43,7 @@ func (n *Namespace) bindKeys(aa ui.KeyActions) { func (n *Namespace) switchNs(app *App, model ui.Tabular, gvr, path string) { n.useNamespace(path) - if err := app.gotoResource("pods", "", false); err != nil { - app.Flash().Err(err) - } + app.gotoResource("pods", "", false) } func (n *Namespace) useNsCmd(evt *tcell.EventKey) *tcell.EventKey { diff --git a/internal/view/picker.go b/internal/view/picker.go index 3fe8f5c1..730311a8 100644 --- a/internal/view/picker.go +++ b/internal/view/picker.go @@ -49,6 +49,10 @@ func (p *Picker) Init(ctx context.Context) error { return nil } +func (*Picker) InCmdMode() bool { + return false +} + // Start starts the view. func (p *Picker) Start() {} diff --git a/internal/view/pod.go b/internal/view/pod.go index 1fd08cea..d77f006f 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -34,10 +34,10 @@ type Pod struct { // NewPod returns a new viewer. func NewPod(gvr client.GVR) ResourceViewer { - p := Pod{} + var p Pod p.ResourceViewer = NewPortForwardExtender( NewImageExtender( - NewLogsExtender(NewBrowser(gvr), p.selectedContainer), + NewLogsExtender(NewBrowser(gvr), p.logOptions), ), ) p.AddBindKeysFn(p.bindKeys) @@ -85,21 +85,37 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { aa.Add(resourceSorters(p.GetTable())) } -func (p *Pod) selectedContainer() string { +func (p *Pod) logOptions() (*dao.LogOptions, error) { path := p.GetTable().GetSelectedItem() if path == "" { - return "" + return nil, errors.New("you must provide a selection") } - cc, err := fetchContainers(p.App().factory, path, true) + pod, err := fetchPod(p.App().factory, path) if err != nil { - log.Error().Err(err).Msgf("Fetch containers") - return "" + return nil, err } - if len(cc) == 1 { - return cc[0] + + cc := fetchContainers(pod.Spec, true) + + cfg := p.App().Config.K9s.Logger + opts := dao.LogOptions{ + Path: path, + Lines: int64(cfg.TailCount), + SinceSeconds: cfg.SinceSeconds, + SingleContainer: len(cc) == 1, + AllContainers: false, + ShowTimestamp: cfg.ShowTime, } - return "" + if c, ok := dao.GetDefaultLogContainer(pod.ObjectMeta, pod.Spec); ok { + opts.Container, opts.DefaultContainer = c, c + } else if len(cc) == 1 { + opts.Container = cc[0] + } else { + opts.AllContainers = true + } + + return &opts, nil } func (p *Pod) showContainers(app *App, model ui.Tabular, gvr, path string) { @@ -221,10 +237,11 @@ func containerShellin(a *App, comp model.Component, path, co string) error { return nil } - cc, err := fetchContainers(a.factory, path, false) + pod, err := fetchPod(a.factory, path) if err != nil { return err } + cc := fetchContainers(pod.Spec, false) if len(cc) == 1 { resumeShellIn(a, comp, path, cc[0]) return nil @@ -234,11 +251,8 @@ func containerShellin(a *App, comp model.Component, path, co string) error { picker.SetSelectedFunc(func(_ int, co, _ string, _ rune) { resumeShellIn(a, comp, path, co) }) - if err := a.inject(picker); err != nil { - return err - } - return nil + return a.inject(picker) } func resumeShellIn(a *App, c model.Component, path, co string) { @@ -267,10 +281,11 @@ func containerAttachIn(a *App, comp model.Component, path, co string) error { return nil } - cc, err := fetchContainers(a.factory, path, false) + pod, err := fetchPod(a.factory, path) if err != nil { return err } + cc := fetchContainers(pod.Spec, false) if len(cc) == 1 { resumeAttachIn(a, comp, path, cc[0]) return nil @@ -328,24 +343,22 @@ func buildShellArgs(cmd, path, co string, kcfg *string) []string { return args } -func fetchContainers(f dao.Factory, path string, includeInit bool) ([]string, error) { - pod, err := fetchPod(f, path) - if err != nil { - return nil, err - } - - nn := make([]string, 0, len(pod.Spec.Containers)+len(pod.Spec.InitContainers)) - for _, c := range pod.Spec.Containers { +func fetchContainers(spec v1.PodSpec, allContainers bool) []string { + nn := make([]string, 0, len(spec.Containers)+len(spec.InitContainers)) + for _, c := range spec.Containers { nn = append(nn, c.Name) } - if !includeInit { - return nn, nil + if !allContainers { + return nn } - for _, c := range pod.Spec.InitContainers { + for _, c := range spec.InitContainers { + nn = append(nn, c.Name) + } + for _, c := range spec.EphemeralContainers { nn = append(nn, c.Name) } - return nn, nil + return nn } func fetchPod(f dao.Factory, path string) (*v1.Pod, error) { diff --git a/internal/view/pulse.go b/internal/view/pulse.go index d0e2540a..c9094c07 100644 --- a/internal/view/pulse.go +++ b/internal/view/pulse.go @@ -108,6 +108,10 @@ func (p *Pulse) Init(ctx context.Context) error { return nil } +func (*Pulse) InCmdMode() bool { + return false +} + // StylesChanged notifies the skin changed. func (p *Pulse) StylesChanged(s *config.Styles) { p.SetBackgroundColor(s.Charts().BgColor.Color()) @@ -201,7 +205,7 @@ func (p *Pulse) bindKeys() { }) for i, v := range p.charts { - t := strings.Title(client.NewGVR(v.(Graphable).ID()).R()) + t := strings.Title(client.NewGVR(v.ID()).R()) p.actions[tcell.Key(ui.NumKeys[i])] = ui.NewKeyAction(t, p.sparkFocusCmd(i), true) } } @@ -307,9 +311,7 @@ func (p *Pulse) enterCmd(evt *tcell.EventKey) *tcell.EventKey { if res == "cpu" || res == "mem" { res = "pod" } - if err := p.App().gotoResource(res+" all", "", false); err != nil { - p.App().Flash().Err(err) - } + p.App().gotoResource(res+" all", "", false) return nil } @@ -388,7 +390,7 @@ func findIndex(pp []Graphable, p tview.Primitive) int { func findIndexGVR(pp []Graphable, gvr string) (int, bool) { for i, v := range pp { - if v.(Graphable).ID() == gvr { + if v.ID() == gvr { return i, true } } diff --git a/internal/view/reference.go b/internal/view/reference.go index 322f9060..154ea852 100644 --- a/internal/view/reference.go +++ b/internal/view/reference.go @@ -54,10 +54,7 @@ func (r *Reference) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { path := r.GetTable().GetSelectedItem() gvr := ui.TrimCell(r.GetTable().SelectTable, row, 2) - - if err := r.App().gotoResource(client.NewGVR(gvr).R(), path, false); err != nil { - r.App().Flash().Err(err) - } + r.App().gotoResource(client.NewGVR(gvr).R(), path, false) return evt } diff --git a/internal/view/registrar.go b/internal/view/registrar.go index 1a4543fa..637271e7 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -135,9 +135,13 @@ func rbacViewers(vv MetaViewers) { } func batchViewers(vv MetaViewers) { + vv[client.NewGVR("batch/v1/cronjobs")] = MetaViewer{ + viewerFn: NewCronJob, + } vv[client.NewGVR("batch/v1beta1/cronjobs")] = MetaViewer{ viewerFn: NewCronJob, } + vv[client.NewGVR("batch/v1/jobs")] = MetaViewer{ viewerFn: NewJob, } @@ -155,7 +159,5 @@ func extViewers(vv MetaViewers) { func showCRD(app *App, _ ui.Tabular, _, path string) { _, crdGVR := client.Namespaced(path) tokens := strings.Split(crdGVR, ".") - if err := app.gotoResource(tokens[0], "", false); err != nil { - app.Flash().Err(err) - } + app.gotoResource(tokens[0], "", false) } diff --git a/internal/view/sanitizer.go b/internal/view/sanitizer.go index b2b214ba..6e1b1279 100644 --- a/internal/view/sanitizer.go +++ b/internal/view/sanitizer.go @@ -84,6 +84,10 @@ func (s *Sanitizer) Init(ctx context.Context) error { return nil } +func (*Sanitizer) InCmdMode() bool { + return false +} + // ExtraHints returns additional hints. func (s *Sanitizer) ExtraHints() map[string]string { if s.app.Config.K9s.NoIcons { @@ -217,9 +221,7 @@ func (s *Sanitizer) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if len(strings.Split(path, "/")) == 1 && spec.GVR() != "node" { path = "-/" + path } - if err := s.app.gotoResource(client.NewGVR(spec.GVR()).R(), path, false); err != nil { - log.Debug().Err(err) - } + s.app.gotoResource(client.NewGVR(spec.GVR()).R(), path, false) return nil } diff --git a/internal/view/scale_extender.go b/internal/view/scale_extender.go index adce5df8..26658ff6 100644 --- a/internal/view/scale_extender.go +++ b/internal/view/scale_extender.go @@ -49,7 +49,12 @@ func (s *ScaleExtender) scaleCmd(evt *tcell.EventKey) *tcell.EventKey { } func (s *ScaleExtender) showScaleDialog(path string) { - confirm := tview.NewModalForm("", s.makeScaleForm(path)) + form, err := s.makeScaleForm(path) + if err != nil { + s.App().Flash().Err(err) + return + } + confirm := tview.NewModalForm("", form) confirm.SetText(fmt.Sprintf("Scale %s %s", s.GVR(), path)) confirm.SetDoneFunc(func(int, string) { s.dismissDialog() @@ -58,10 +63,30 @@ func (s *ScaleExtender) showScaleDialog(path string) { s.App().Content.ShowPage(scaleDialogKey) } -func (s *ScaleExtender) makeScaleForm(sel string) *tview.Form { +func (s *ScaleExtender) valueOf(col string, index int) (string, error) { + data := s.GetTable().GetFilteredData() + colIdx := data.IndexOfHeader(col) + if colIdx < 0 { + return "", fmt.Errorf("no column index for %s", col) + } + if index > len(data.RowEvents) { + return "", fmt.Errorf("invalid row index %d", index) + } + + return data.RowEvents[index].Row.Fields[colIdx], nil +} + +func (s *ScaleExtender) makeScaleForm(sel string) (*tview.Form, error) { f := s.makeStyledForm() - replicas := strings.TrimSpace(s.GetTable().GetCell(s.GetTable().GetSelectedRowIndex(), s.GetTable().NameColIndex()+1).Text) + + replicas, err := s.valueOf("READY", s.GetTable().GetSelectedRowIndex()) + if err != nil { + return nil, err + } tokens := strings.Split(replicas, "/") + if len(tokens) < 2 { + return nil, fmt.Errorf("unable to locate replicas from %s", replicas) + } replicas = strings.TrimRight(tokens[1], ui.DeltaSign) f.AddInputField("Replicas:", replicas, 4, func(textToCheck string, lastChar rune) bool { _, err := strconv.Atoi(textToCheck) @@ -91,7 +116,7 @@ func (s *ScaleExtender) makeScaleForm(sel string) *tview.Form { s.dismissDialog() }) - return f + return f, nil } func (s *ScaleExtender) dismissDialog() { diff --git a/internal/view/sts.go b/internal/view/sts.go index 5d74f2fb..d7cab256 100644 --- a/internal/view/sts.go +++ b/internal/view/sts.go @@ -1,13 +1,13 @@ package view import ( + "errors" + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" appsv1 "k8s.io/api/apps/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" ) // StatefulSet represents a statefulset viewer. @@ -17,17 +17,16 @@ type StatefulSet struct { // NewStatefulSet returns a new viewer. func NewStatefulSet(gvr client.GVR) ResourceViewer { - s := StatefulSet{ - ResourceViewer: NewPortForwardExtender( - NewRestartExtender( - NewScaleExtender( - NewImageExtender( - NewLogsExtender(NewBrowser(gvr), nil), - ), + var s StatefulSet + s.ResourceViewer = NewPortForwardExtender( + NewRestartExtender( + NewScaleExtender( + NewImageExtender( + NewLogsExtender(NewBrowser(gvr), s.logOptions), ), ), ), - } + ) s.AddBindKeysFn(s.bindKeys) s.GetTable().SetEnterFn(s.showPods) s.GetTable().SetColorerFn(render.StatefulSet{}.ColorerFunc()) @@ -35,6 +34,48 @@ func NewStatefulSet(gvr client.GVR) ResourceViewer { return &s } +func (s *StatefulSet) logOptions() (*dao.LogOptions, error) { + path := s.GetTable().GetSelectedItem() + if path == "" { + return nil, errors.New("you must provide a selection") + } + + sts, err := s.sts(path) + if err != nil { + return nil, err + } + + cc := sts.Spec.Template.Spec.Containers + var ( + co, dco string + allCos bool + ) + if c, ok := dao.GetDefaultLogContainer(sts.Spec.Template.ObjectMeta, sts.Spec.Template.Spec); ok { + co, dco = c, c + } else if len(cc) == 1 { + co = cc[0].Name + } else { + dco, allCos = cc[0].Name, true + } + + cfg := s.App().Config.K9s.Logger + opts := dao.LogOptions{ + Path: path, + Container: co, + Lines: int64(cfg.TailCount), + SingleContainer: len(cc) == 1, + SinceSeconds: cfg.SinceSeconds, + AllContainers: allCos, + ShowTimestamp: cfg.ShowTime, + } + if co == "" { + opts.AllContainers = true + } + opts.DefaultContainer = dco + + return &opts, nil +} + func (s *StatefulSet) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ ui.KeyShiftR: ui.NewKeyAction("Sort Ready", s.GetTable().SortColCmd(readyCol, true), false), @@ -52,16 +93,6 @@ func (s *StatefulSet) showPods(app *App, _ ui.Tabular, _, path string) { } func (s *StatefulSet) sts(path string) (*appsv1.StatefulSet, error) { - o, err := s.App().factory.Get(s.GVR().String(), path, true, labels.Everything()) - if err != nil { - return nil, err - } - - var sts appsv1.StatefulSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts) - if err != nil { - return nil, err - } - - return &sts, nil + var sts dao.StatefulSet + return sts.Load(s.App().factory, path) } diff --git a/internal/view/types.go b/internal/view/types.go index 76216cc9..457170f8 100644 --- a/internal/view/types.go +++ b/internal/view/types.go @@ -4,6 +4,7 @@ import ( "context" "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/ui" ) @@ -29,8 +30,8 @@ type ( // EnterFunc represents an enter key action. EnterFunc func(app *App, model ui.Tabular, gvr, path string) - // ContainerFunc returns the active container name. - ContainerFunc func() string + // LogOptionsFunc returns the active log options. + LogOptionsFunc func() (*dao.LogOptions, error) // ContextFunc enhances a given context. ContextFunc func(context.Context) context.Context diff --git a/internal/view/xray.go b/internal/view/xray.go index 2dc5019e..21903781 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -92,6 +92,10 @@ func (x *Xray) Init(ctx context.Context) error { return nil } +func (*Xray) InCmdMode() bool { + return false +} + // ExtraHints returns additional hints. func (x *Xray) ExtraHints() map[string]string { if x.app.Config.K9s.NoIcons { @@ -262,7 +266,12 @@ func (x *Xray) showLogs(spec *xray.NodeSpec, prev bool) { return } - if err := x.app.inject(NewLog(client.NewGVR("v1/pods"), path, co, prev)); err != nil { + opts := dao.LogOptions{ + Path: path, + Container: co, + Previous: prev, + } + if err := x.app.inject(NewLog(client.NewGVR("v1/pods"), &opts)); err != nil { x.app.Flash().Err(err) } } @@ -448,9 +457,7 @@ func (x *Xray) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if len(strings.Split(spec.Path(), "/")) == 1 { return nil } - if err := x.app.gotoResource(client.NewGVR(spec.GVR()).R(), spec.Path(), false); err != nil { - x.app.Flash().Err(err) - } + x.app.gotoResource(client.NewGVR(spec.GVR()).R(), spec.Path(), false) return nil }