diff --git a/README.md b/README.md
index d9f5510c..3984f22a 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,8 @@ K9s is available on Linux, macOS and Windows platforms.
export K9S_EDITOR=my_fav_editor
```
+* K9s prefers recent kubernetes versions ie 1.16+
+
---
## The Command Line
@@ -264,11 +266,13 @@ K9s uses aliases to navigate most K8s resources.
k9s:
# Represents ui poll intervals. Default 2secs
refreshRate: 2
+ # Number of retries once the connection to the api-server is lost. Default 15.
+ maxConnRetry: 5
# Enable mouse support. Default false
- enableMouse: false
+ enableMouse: true
# Set to true to hide K9s header. Default false
headless: false
- # Set to true to hide K9s footer. Default false
+ # Set to true to hide K9s crumbs. Default false
crumbsless: false
# Indicates whether modification commands like delete/kill/edit are disabled. Default is false
readOnly: false
@@ -744,7 +748,7 @@ k9s:
## Known Issues
This is still work in progress! If something is broken or there's a feature
-that you want, please open a PR or file a ticket.
+that you want, please file an issue and if so inclined submit a PR!
K9s will most likely blow up if...
@@ -766,7 +770,9 @@ to make this project a reality!
* [Fernand Galiana](https://github.com/derailed)
*
fernand@imhotep.io
*
[@kitesurfer](https://twitter.com/kitesurfer?lang=en)
-We always enjoy hearing from folks who benefit from our work.
+
+We always enjoy hearing from folks who benefit from our work!
+
---
© 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
diff --git a/change_logs/release_v0.23.0.md b/change_logs/release_v0.23.0.md
index 462ec061..247ca3c5 100644
--- a/change_logs/release_v0.23.0.md
+++ b/change_logs/release_v0.23.0.md
@@ -18,7 +18,7 @@ I figured why not share one of the tunes I was spinning when powering thru teh b
[On An Island - David Gilmour With Crosby&Nash](https://www.youtube.com/watch?v=kEa__0wtIRo)
-## Our K9s Heroes
+## Our Release Heroes...
Please join me in recognizing and applauding this drop contributors that went the extra mile to make sure K9s is better and more useful for all of us!!
@@ -45,17 +45,21 @@ First off I would like to send a `Big Thank You` to the following generous K9s f
* [Matt Welke](https://github.com/mattwelke)
* [Stefan Mikolajczyk](https://github.com/stefanmiko)
-Contrarily to popular belief, OSS is not free! We've now reached ~9k stars and 300k downloads! As you all know, this project is not pimped out by a big company with deep pockets or a large team. K9s is complex and does demand a lot of my time. So if this tool is useful to you or your organization and part of your daily Kubernetes lifecycle, please contribute! Your contribution whether financial, PRs, issues or shout-outs on social/blogs are crucial to keep K9s growing and powerful for all of us. Don't let OSS by individual contributors become an oxymoron!
+Contrarily to popular belief, OSS is not free! We've now reached ~9k stars and 300k downloads! As you all know, this project is not pimped out by a big company with deep pockets. K9s is complex and does demand lots of my time. So if this tool is useful to you and benefits you and your organization in your Kubernetes journey, please contribute! Your contribution whether financial, PRs, issues or shout-outs on social/blogs are crucial to keep K9s growing and powerful for all of us. Don't let OSS by individual contributors become an oxymoron!
-## Full Screen
+## Describe/YAML views goes FullMonty
-We've added a new option to enable full screen while describing or viewing a resource YAML namely `f`. This works similarly to the full screen toggle option while viewing logs ie pressing `f` will toggle fullscreen on/off.
+We've added a new option to enable full screen while describing or viewing a resource YAML. Similarly to the full screen toggle option in the log view, pressing `f` will now toggle fullscreen for both YAML and Describe views.
+
+Additionally, the YAML and Describe view are now reactive! YAML/Describe views will now watch for changes to the underlying resource manifests. How cool is that?
+
+Not cool enough for Ya? the YAML view also affords for getting ride of those pesky `managedFields` while viewing a resource. Pressing `m` will toggle visibility on these fields.
## Best Effort... Not!
-In this drop, we've added 2 new columns to the Pod/Container views namely `CPU(R:L)` and `MEM(R:L)`. These represents the current request/limit resources specified at either the pod or container level. While in Pod view, you will need to use the wide command `Ctrl-W` to see the resources set at the pod level or you can leverage K9s column customization feature to volunteer them while in Pod view. In the Container view these columns will be available by default.
+In this drop, we've added 2 new columns to the Pod/Container views namely `CPU(R:L)` and `MEM(R:L)`. These represents the current request:limit resources specified at either the pod or container level. While in Pod view, you will need to use the `Go Wide` option `Ctrl-W` to see the resources set at the pod level. You can also leverage K9s [Custom Column](https://github.com/derailed/k9s#resource-custom-columns) feature to volunteer them while in Pod view. In the Container view these columns will be available by default.
-## Container Images
+## Set Container Images
You have now the ability to tweak your container images for experimentation, using the new SetImage binding aka `i`. This feature is available for unmanaged pods, deployments, sts and ds. With a resource selected, pressing `i` will provision an edit dialog listing all init/container images.
@@ -63,7 +67,7 @@ NOTE! This is a one shot commands applied directly against your cluster and won'
## Crumbs On, Crumbs Off, Caterpillar
-We've added a new configuration to turn off the crumbs via `crumbsLess` configuration option. You can also toggle the crumbs via the new key option `C`. You can enable/disable this option in your ~/.k9s/config.yml or via command line using `--crumbsless` flag.
+We've added a new configuration to turn off the crumbs via `crumbsLess` configuration option. You can also toggle the crumbs via the new key option `C`. You can enable/disable this option in your ~/.k9s/config.yml or via command line using `--crumbsless` CLI option.
```yaml
k9s:
@@ -74,30 +78,28 @@ k9s:
...
```
-## FILTER...NOT!
+## BANG FILTERS!
-Some folks have voiced the desire to use inverse filters while filtering to content in the resource table views. There is now a new filter option available when performing these filtering operations. For example, in order to see all pods that are not named `fred` you can now use `/!fred` as your filtering command.
-
-## Disturbance In the Keyboard Force...
-
-In this drop we've changed the key binding to toggle the header from `Ctrl-E` to `H`
+Some folks have voiced the desire to use inverse filters to refine content while in resource table views. Prepending a `!` to your filter will now enable an inverse filtering operation For example, in order to see all pods that do not contain `fred` in their name, you can now use `/!fred` as your filtering command.
---
## Resolved Issues/Features
* [Issue #906](https://github.com/derailed/k9s/issues/906) Print resources in pod view
+* [Issue #901](https://github.com/derailed/k9s/issues/901) Logs page for any pod/container shows Waiting for logs...
* [Issue #900](https://github.com/derailed/k9s/issues/900) Support sort by pending status
* [Issue #895](https://github.com/derailed/k9s/issues/895) Wrong highlight position when filtering logs
* [Issue #892](https://github.com/derailed/k9s/issues/892) tacit kustomize & kpt support
* [Issue #889](https://github.com/derailed/k9s/issues/889) Disable read only config via command line flag
-*
-* [Issue #886](https://github.com/derailed/k9s/issues/886) Full screen mode or remove borders in YAML view for easy copy/paste
* [Issue #887](https://github.com/derailed/k9s/issues/887) Ability to call out a separate program to parse/filter logs
+* [Issue #886](https://github.com/derailed/k9s/issues/886) Full screen mode or remove borders in YAML view for easy copy/paste
* [Issue #884](https://github.com/derailed/k9s/issues/884) Refresh for describe & yaml view
* [Issue #883](https://github.com/derailed/k9s/issues/883) View logs quickly scrolls through entire logs when initially loading
* [Issue #875](https://github.com/derailed/k9s/issues/875) Lazy filter
* [Issue #848](https://github.com/derailed/k9s/issues/848) Support an inverse operator on filtered search
+* [Issue #820](https://github.com/derailed/k9s/issues/820) Log file spammed despite K9s not running
+* [Issue #794](https://github.com/derailed/k9s/issues/794) Events view
## Resolved PRs
diff --git a/go.mod b/go.mod
index a3dbe81b..e6710611 100644
--- a/go.mod
+++ b/go.mod
@@ -39,6 +39,7 @@ require (
k8s.io/client-go v0.18.8
k8s.io/klog v1.0.0
k8s.io/kubectl v0.18.2
+ k8s.io/kubernetes v1.13.0
k8s.io/metrics v0.18.8
rsc.io/letsencrypt v0.0.3 // indirect
sigs.k8s.io/yaml v1.2.0
diff --git a/go.sum b/go.sum
index 9c86cbf1..17c3dfa6 100644
--- a/go.sum
+++ b/go.sum
@@ -3,6 +3,17 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
+cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+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/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=
@@ -11,6 +22,7 @@ github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW
github.com/Azure/go-autorest v14.0.0+incompatible h1:r/ug62X9o8vikt53/nkAPmFmzfSrCCAplPH7wa+mK0U=
github.com/Azure/go-autorest v14.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
@@ -29,6 +41,7 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
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/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
@@ -106,6 +119,9 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
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/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@@ -179,6 +195,7 @@ 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/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=
@@ -196,6 +213,8 @@ github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
+github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
@@ -205,6 +224,8 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko=
@@ -219,12 +240,15 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
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-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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY=
+github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -299,8 +323,11 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
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/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -332,13 +359,19 @@ 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/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/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 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/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/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 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -371,6 +404,7 @@ 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/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.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@@ -391,7 +425,10 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -401,9 +438,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi
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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
@@ -453,6 +492,8 @@ github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/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=
@@ -465,6 +506,8 @@ github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/5
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=
+github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
+github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -531,6 +574,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
+github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -543,6 +588,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -550,6 +597,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rakyll/hey v0.1.3 h1:OxaaU+3P16QGT4tccjFgZ51havtIZTgTshnUc62JPBE=
github.com/rakyll/hey v0.1.3/go.mod h1:nAOTOo+L52KB9SZq/M6J18kxjto4yVtXQDjU2HgjUPI=
@@ -583,6 +632,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
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/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -639,6 +690,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 h1:j2hhcujLRHAg872RWAV5yaUrEjHEObwDv3aImCaNLek=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
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/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
@@ -657,6 +709,7 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/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/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4=
@@ -670,20 +723,41 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+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=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+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=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -698,6 +772,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -706,14 +781,21 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU=
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 h1:pE8b58s1HRDMi8RDc79m0HISf9D4TzseP40cEA6IGfs=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -732,33 +814,49 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
+golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -767,23 +865,43 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+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/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
@@ -791,14 +909,21 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587 h1:1Ym+vvUpq1ZHvxzn34gENJX8U4aKO+vhy2P/2+Xl6qQ=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
@@ -815,6 +940,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
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=
@@ -847,17 +975,22 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
helm.sh/helm/v3 v3.2.0 h1:V12EGAmr2DJ/fWrPo2fPdXWSIXvlXm51vGkQIXMeymE=
helm.sh/helm/v3 v3.2.0/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ=
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/api v0.18.8 h1:aIKUzJPb96f3fKec2lxtY7acZC9gQNDLVhfSGpxBAC4=
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
+k8s.io/api v0.19.3 h1:GN6ntFnv44Vptj/b+OnMW7FmzkpDoIDLZRvKX3XH9aU=
+k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs=
k8s.io/apiextensions-apiserver v0.18.0 h1:HN4/P8vpGZFvB5SOMuPPH2Wt9Y/ryX+KRvIyAkchu1Q=
k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo=
k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
@@ -866,6 +999,8 @@ k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA=
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.8 h1:jimPrycCqgx2QPearX3to1JePz7wSbVLq+7PdBTTwQ0=
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
+k8s.io/apimachinery v0.19.3 h1:bpIQXlKjB4cB/oNpnNnV+BybGPR7iP5oYpsOTEJ4hgc=
+k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw=
k8s.io/cli-runtime v0.18.0 h1:jG8XpSqQ5TrV0N+EZ3PFz6+gqlCk71dkggWCCq9Mq34=
k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ=
@@ -873,33 +1008,50 @@ k8s.io/cli-runtime v0.18.2 h1:JiTN5RgkFNTiMxHBRyrl6n26yKWAuNRlei1ZJALUmC8=
k8s.io/cli-runtime v0.18.2/go.mod h1:yfFR2sQQzDsV0VEKGZtrJwEy4hLZ2oj4ZIfodgxAHWQ=
k8s.io/cli-runtime v0.18.8 h1:ycmbN3hs7CfkJIYxJAOB10iW7BVPmXGXkfEyiV9NJ+k=
k8s.io/cli-runtime v0.18.8/go.mod h1:7EzWiDbS9PFd0hamHHVoCY4GrokSTPSL32MA4rzIu0M=
+k8s.io/cli-runtime v0.19.3 h1:vZUTphJIvlh7+867cXiLmyzoCAuQdukbPLIad6eEajQ=
+k8s.io/cli-runtime v0.19.3/go.mod h1:q+l845i5/uWzcUpCrl+L4f3XLaJi8ZeLVQ/decwty0A=
k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE=
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
k8s.io/client-go v0.18.8 h1:SdbLpIxk5j5YbFr1b7fq8S7mDgDjYmUxSbszyoesoDM=
k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
+k8s.io/client-go v0.19.3 h1:ctqR1nQ52NUs6LpI0w+a5U+xjYwflFwA13OJKcicMxg=
+k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM=
k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/code-generator v0.18.8/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
+k8s.io/code-generator v0.19.3/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
k8s.io/component-base v0.18.0 h1:I+lP0fNfsEdTDpHaL61bCAqTZLoiWjEEP304Mo5ZQgE=
k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
k8s.io/component-base v0.18.2 h1:SJweNZAGcUvsypLGNPNGeJ9UgPZQ6+bW+gEHe8uyh/Y=
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
+k8s.io/component-base v0.19.3 h1:c+DzDNAQFlaoyX+yv8YuWi8xmlQvvY5DnJGbaz5U74o=
+k8s.io/component-base v0.19.3/go.mod h1:WhLWSIefQn8W8jxSLl5WNiR6z8oyMe/8Zywg7alOkRc=
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-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
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=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
+k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
+k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
+k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
+k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ=
+k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kubectl v0.18.0 h1:hu52Ndq/d099YW+3sS3VARxFz61Wheiq8K9S7oa82Dk=
k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU=
k8s.io/kubectl v0.18.2 h1:9jnGSOC2DDVZmMUTMi0D1aed438mfQcgqa5TAzVjA1k=
k8s.io/kubectl v0.18.2/go.mod h1:OdgFa3AlsPKRpFFYE7ICTwulXOcMGXHTc+UKhHKvrb4=
+k8s.io/kubectl v0.19.3 h1:T8IHHpg+uRIfn34wqJ8wHG5bbH+VV5FNPtJ+jKcho1U=
+k8s.io/kubectl v0.19.3/go.mod h1:t5cscfrAuHUvEGNyNJjPKt+rGlaJzk8jrKYHXxEsANE=
+k8s.io/kubernetes v1.13.0 h1:qTfB+u5M92k2fCCCVP2iuhgwwSOv1EkAkvQY1tQODD8=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/metrics v0.18.0 h1:yTt/yuRVW1XfnBg8DcOGecW+rrR7VxrMUXYIiUqSELE=
k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4=
@@ -907,8 +1059,13 @@ k8s.io/metrics v0.18.2 h1:v4J7WKu/Zo/htSH3w//UWJZT9/CpUThXWYyUbQ/F/jY=
k8s.io/metrics v0.18.2/go.mod h1:qga8E7QfYNR9Q89cSCAjinC9pTZ7yv1XSVGUB0vJypg=
k8s.io/metrics v0.18.8 h1:Obf262GVd2Uy+WbPkOXNiZroI5mT8zYoKK3Y/8KF7Yc=
k8s.io/metrics v0.18.8/go.mod h1:j7JzZdiyhLP2BsJm/Fzjs+j5Lb1Y7TySjhPWqBPwRXA=
+k8s.io/metrics v0.19.3 h1:p/goUqtdCslX76mSNowzZkNxiKzNRQW4bUP02U34+QQ=
+k8s.io/metrics v0.19.3/go.mod h1:Eap/Lk1FiAIjkaArFuv41v+ph6dbDpVGwAg7jMI+4vg=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
+k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM=
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
@@ -917,6 +1074,8 @@ sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5
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.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.1/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=
diff --git a/internal/client/metrics.go b/internal/client/metrics.go
index 0a4e48b6..ad979500 100644
--- a/internal/client/metrics.go
+++ b/internal/client/metrics.go
@@ -268,7 +268,7 @@ func ToPercentage(v1, v2 int64) int {
// ToPercentageStr computes percentage, but if v2 is 0, it will return NAValue instead of 0
func ToPercentageStr(v1, v2 int64) string {
if v2 == 0 {
- return NA
+ return "0"
}
return strconv.Itoa(ToPercentage(v1, v2))
}
diff --git a/internal/dao/node.go b/internal/dao/node.go
index 2d1986dc..fc14ccd1 100644
--- a/internal/dao/node.go
+++ b/internal/dao/node.go
@@ -137,11 +137,6 @@ func (n *Node) Get(ctx context.Context, path string) (runtime.Object, error) {
// List returns a collection of node resources.
func (n *Node) List(ctx context.Context, ns string) ([]runtime.Object, error) {
- labels, ok := ctx.Value(internal.KeyLabels).(string)
- if !ok {
- log.Warn().Msgf("No label selector found in context")
- }
-
var (
nmx *mv1beta1.NodeMetricsList
err error
@@ -152,6 +147,7 @@ func (n *Node) List(ctx context.Context, ns string) ([]runtime.Object, error) {
}
}
+ labels, _ := ctx.Value(internal.KeyLabels).(string)
nn, err := FetchNodes(ctx, n.Factory, labels)
if err != nil {
return nil, err
@@ -166,11 +162,14 @@ func (n *Node) List(ctx context.Context, ns string) ([]runtime.Object, error) {
if !ok {
return nil, fmt.Errorf("expecting interface map but got `%T", o)
}
- pCount, _ := n.CountPods(meta["name"].(string))
+ pods, err := n.GetPods(meta["name"].(string))
+ if err != nil {
+ return nil, err
+ }
oo[i] = &render.NodeWithMetrics{
- Raw: &unstructured.Unstructured{Object: o},
- MX: nodeMetricsFor(MetaFQN(no.ObjectMeta), nmx),
- PodCount: pCount,
+ Raw: &unstructured.Unstructured{Object: o},
+ MX: nodeMetricsFor(MetaFQN(no.ObjectMeta), nmx),
+ Pods: pods,
}
}
@@ -202,6 +201,27 @@ func (n *Node) CountPods(nodeName string) (int, error) {
return count, nil
}
+// GetPods returns all pods running on given node.
+func (n *Node) GetPods(nodeName string) ([]*v1.Pod, error) {
+ oo, err := n.Factory.List("v1/pods", client.AllNamespaces, false, labels.Everything())
+ if err != nil {
+ return nil, err
+ }
+
+ pp := make([]*v1.Pod, 0, len(oo))
+ for _, o := range oo {
+ po := new(v1.Pod)
+ if err := runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, po); err != nil {
+ return nil, err
+ }
+ if po.Spec.NodeName == nodeName {
+ pp = append(pp, po)
+ }
+ }
+
+ return pp, nil
+}
+
// ----------------------------------------------------------------------------
// Helpers...
diff --git a/internal/model/describe.go b/internal/model/describe.go
index 69a00eb6..4676ffeb 100644
--- a/internal/model/describe.go
+++ b/internal/model/describe.go
@@ -21,11 +21,14 @@ type ResourceViewerListener interface {
ResourceFailed(error)
}
+type ToggleOpts map[string]bool
+
type ResourceViewer interface {
GetPath() string
Filter(string)
ClearFilter()
Peek() []string
+ SetOptions(context.Context, ToggleOpts)
Watch(context.Context) error
AddListener(ResourceViewerListener)
RemoveListener(ResourceViewerListener)
@@ -56,6 +59,9 @@ func (d *Describe) GetPath() string {
return d.path
}
+// SetOptions toggle model options.
+func (d *Describe) SetOptions(context.Context, ToggleOpts) {}
+
// Filter filters the model.
func (d *Describe) Filter(q string) {
d.query = q
diff --git a/internal/model/yaml.go b/internal/model/yaml.go
index f4808537..c3296e6c 100644
--- a/internal/model/yaml.go
+++ b/internal/model/yaml.go
@@ -18,18 +18,23 @@ import (
"github.com/sahilm/fuzzy"
)
-const maxRetryInterval = 1 * time.Minute
+const (
+ maxRetryInterval = 1 * time.Minute
+
+ // ManageFieldOpts tracks managed fields.
+ ManagedFieldsOpts = "ManagedFields"
+)
// YAML tracks yaml resource representations.
type YAML struct {
- gvr client.GVR
- inUpdate int32
- showManagedFields bool
- path string
- query string
- lines []string
- refreshRate time.Duration
- listeners []ResourceViewerListener
+ gvr client.GVR
+ inUpdate int32
+ path string
+ query string
+ lines []string
+ refreshRate time.Duration
+ listeners []ResourceViewerListener
+ options ToggleOpts
}
// NewYAML return a new yaml resource model.
@@ -46,6 +51,14 @@ func (y *YAML) GetPath() string {
return y.path
}
+// SetOptions toggle model options.
+func (y *YAML) SetOptions(ctx context.Context, opts ToggleOpts) {
+ y.options = opts
+ if err := y.refresh(ctx); err != nil {
+ y.fireResourceFailed(err)
+ }
+}
+
// Filter filters the model.
func (y *YAML) Filter(q string) {
y.query = q
@@ -156,7 +169,7 @@ func (y *YAML) refresh(ctx context.Context) error {
}
func (y *YAML) reconcile(ctx context.Context) error {
- s, err := y.ToYAML(ctx, y.gvr, y.path, y.showManagedFields)
+ s, err := y.ToYAML(ctx, y.gvr, y.path, y.options[ManagedFieldsOpts])
if err != nil {
return err
}
diff --git a/internal/render/container.go b/internal/render/container.go
index b210c217..c2f23aed 100644
--- a/internal/render/container.go
+++ b/internal/render/container.go
@@ -6,7 +6,6 @@ import (
"strconv"
"strings"
- "github.com/derailed/k9s/internal/client"
"github.com/derailed/tview"
"github.com/gdamore/tcell"
v1 "k8s.io/api/core/v1"
@@ -76,13 +75,13 @@ func (Container) Header(ns string) Header {
HeaderColumn{Name: "INIT"},
HeaderColumn{Name: "RESTARTS", Align: tview.AlignRight},
HeaderColumn{Name: "PROBES(L:R)"},
- HeaderColumn{Name: "CPU(R:L)", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "MEM(R:L)", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "CPU", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "MEM", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU/R:L", Align: tview.AlignRight},
+ HeaderColumn{Name: "MEM/R:L", Align: tview.AlignRight},
HeaderColumn{Name: "%CPU/R", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "%MEM/R", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%CPU/L", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "%MEM/R", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%MEM/L", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "PORTS"},
HeaderColumn{Name: "VALID", Wide: true},
@@ -97,7 +96,7 @@ func (c Container) Render(o interface{}, name string, r *Row) error {
return fmt.Errorf("Expected ContainerRes, but got %T", o)
}
- cur, perc, limit, res := gatherMetrics(co.Container, co.MX)
+ cur, perc, res := gatherMetrics(co.Container, co.MX)
ready, state, restarts := "false", MissingValue, "0"
if co.Status != nil {
ready, state, restarts = boolToStr(co.Status.Ready), ToContainerState(co.Status.State), strconv.Itoa(int(co.Status.RestartCount))
@@ -113,14 +112,14 @@ func (c Container) Render(o interface{}, name string, r *Row) error {
boolToStr(co.IsInit),
restarts,
probe(co.Container.LivenessProbe) + ":" + probe(co.Container.ReadinessProbe),
- ToResourcesMc(res),
- ToResourcesMi(res),
- cur.cpu,
- cur.mem,
- perc.cpu,
- perc.mem,
- limit.cpu,
- limit.mem,
+ toMc(cur.rCPU().MilliValue()),
+ toMi(cur.rMEM().Value()),
+ toMc(res[requestCPU].MilliValue()) + ":" + toMc(res[limitCPU].MilliValue()),
+ toMi(res[requestMEM].Value()) + ":" + toMi(res[limitMEM].Value()),
+ strconv.Itoa(perc.rCPU()),
+ strconv.Itoa(perc.lCPU()),
+ strconv.Itoa(perc.rMEM()),
+ strconv.Itoa(perc.lMEM()),
ToContainerPorts(co.Container.Ports),
asStatus(c.diagnose(state, ready)),
toAge(co.Age),
@@ -144,50 +143,29 @@ func (Container) diagnose(state, ready string) error {
// ----------------------------------------------------------------------------
// Helpers...
-func gatherMetrics(co *v1.Container, mx *mv1beta1.ContainerMetrics) (c, p, l metric, r resources) {
- c, p, l = noMetric(), noMetric(), noMetric()
-
- r = make(resources, 4)
- rcpu, rmem := containerResources(*co)
- lcpu, lmem := containerLimits(*co)
- if rcpu != nil {
- r[requestCPU] = rcpu
- }
- if rmem != nil {
- r[requestMEM] = rmem
- }
- if lcpu != nil {
- r[limitCPU] = lcpu
- }
- if lmem != nil {
- r[limitMEM] = lmem
- }
+func gatherMetrics(co *v1.Container, mx *mv1beta1.ContainerMetrics) (resources, percentages, resources) {
+ rList, lList := containerRequests(co), co.Resources.Limits
+ c, p, r := newResources(nil, nil), newPercentages(), newResources(rList, lList)
if mx == nil {
- return
+ return c, p, r
}
- cpu := mx.Usage.Cpu().MilliValue()
- mem := client.ToMB(mx.Usage.Memory().Value())
- c = metric{
- cpu: ToMc(cpu),
- mem: ToMi(mem),
+ c[requestCPU], c[requestMEM] = mx.Usage.Cpu(), mx.Usage.Memory()
+ if rList.Cpu() != nil {
+ p[requestCPU] = percentMc(c.rCPU(), rList.Cpu())
+ }
+ if rList.Memory() != nil {
+ p[requestMEM] = percentMi(c.rMEM(), rList.Memory())
}
- if rcpu != nil {
- p.cpu = client.ToPercentageStr(cpu, rcpu.MilliValue())
+ if lList.Cpu() != nil {
+ p[limitCPU] = percentMc(c.lCPU(), lList.Cpu())
}
- if rmem != nil {
- p.mem = client.ToPercentageStr(mem, client.ToMB(rmem.Value()))
+ if rList.Memory() != nil {
+ p[limitMEM] = percentMi(c.lMEM(), lList.Memory())
}
- if lcpu != nil {
- l.cpu = client.ToPercentageStr(cpu, lcpu.MilliValue())
- }
- if lmem != nil {
- l.mem = client.ToPercentageStr(mem, client.ToMB(lmem.Value()))
- }
-
- return
+ return c, p, r
}
// ToContainerPorts returns container ports as a string.
diff --git a/internal/render/container_test.go b/internal/render/container_test.go
index fe098ea9..8241baf2 100644
--- a/internal/render/container_test.go
+++ b/internal/render/container_test.go
@@ -35,14 +35,14 @@ func TestContainer(t *testing.T) {
"false",
"0",
"off:off",
- "20m:20m",
- "100Mi:100Mi",
- "10m",
- "20Mi",
- "50",
+ "10",
"20",
+ "20:20",
+ "100:100",
"50",
+ "0",
"20",
+ "0",
"",
"container is not ready",
},
diff --git a/internal/render/helpers.go b/internal/render/helpers.go
index c52b4cd3..994a949d 100644
--- a/internal/render/helpers.go
+++ b/internal/render/helpers.go
@@ -13,6 +13,8 @@ import (
"github.com/rs/zerolog/log"
"golang.org/x/text/language"
"golang.org/x/text/message"
+ v1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/duration"
)
@@ -52,7 +54,7 @@ func AsThousands(n int64) string {
return p.Sprintf("%d", n)
}
-// Happy returns true if resoure is happy, false otherwise
+// Happy returns true if resource is happy, false otherwise
func Happy(ns string, h Header, r Row) bool {
if len(r.Fields) == 0 {
return true
@@ -81,12 +83,12 @@ func asSelector(s *metav1.LabelSelector) string {
return sel.String()
}
-type metric struct {
- cpu, mem, cpuLim, memLim string
+func percentMc(v1, v2 *resource.Quantity) int {
+ return client.ToPercentage(v1.MilliValue(), v2.MilliValue())
}
-func noMetric() metric {
- return metric{cpu: NAValue, mem: NAValue, cpuLim: NAValue, memLim: NAValue}
+func percentMi(v1, v2 *resource.Quantity) int {
+ return client.ToPercentage(client.ToMB(v1.Value()), client.ToMB(v2.Value()))
}
// ToSelector flattens a map selector to a string selector.
@@ -144,6 +146,15 @@ func join(a []string, sep string) string {
return buff.String()
}
+// AsPerc prints a number as percentage with parans.
+func AsPerc(p string) string {
+ return "(" + p + ")"
+}
+
+func printValAndPerc(v string, p int) string {
+ return strconv.Itoa(p) + "% (" + v + ")"
+}
+
// PrintPerc prints a number as percentage.
func PrintPerc(p int) string {
return strconv.Itoa(p) + "%"
@@ -251,40 +262,54 @@ func mapToIfc(m interface{}) (s string) {
return
}
-// ToResourcesMi prints out request:limit mem resources.
-func ToResourcesMi(res resources) string {
- var v1, v2 int64
- if v, ok := res[requestMEM]; ok && v != nil {
- v1 = v.MilliValue()
- }
- if v, ok := res[limitMEM]; ok && v != nil {
- v2 = v.MilliValue()
- }
- if v1 == 0 && v2 == 0 {
- return NAValue
- }
- return bytesToMb(v1) + ":" + bytesToMb(v2)
+func toCPUPerc(cpu, acpu *resource.Quantity) string {
+ c, ac := cpu.MilliValue(), acpu.MilliValue()
+ return toMc(c) + " " + AsPerc(strconv.Itoa(client.ToPercentage(c, ac)))
+}
+
+func toMEMPerc(mem, amem *resource.Quantity) string {
+ m, am := mem.MilliValue(), amem.MilliValue()
+ return toMi(m) + " " + AsPerc(strconv.Itoa(client.ToPercentage(m, am)))
+}
+
+func toResourcesMcPerc(res resources, a v1.ResourceList) string {
+ cpu := a.Cpu().MilliValue()
+ rcpu, lcpu := toResourcesMc(res)
+ return rcpu +
+ AsPerc(strconv.Itoa(client.ToPercentage(res[requestCPU].MilliValue(), cpu))) + ":" +
+ lcpu +
+ AsPerc(strconv.Itoa(client.ToPercentage(res[limitCPU].MilliValue(), cpu)))
+}
+
+func toMcPerc(v1, v2 *resource.Quantity) string {
+ m := v1.MilliValue()
+ return toMc(m) + " (" +
+ strconv.Itoa(client.ToPercentage(m, v2.MilliValue())) + "%)"
+}
+
+func toMiPerc(v1, v2 *resource.Quantity) string {
+ m := v1.Value()
+ return toMi(m) + " (" +
+ strconv.Itoa(client.ToPercentage(m, v2.Value())) + "%)"
}
func toMc(v int64) string {
if v == 0 {
- return NAValue
+ return ZeroValue
}
p := message.NewPrinter(language.English)
- return p.Sprintf("%dm", v)
+ return p.Sprintf("%d", v)
}
-func bytesToMb(v int64) string {
+func toMi(v int64) string {
if v == 0 {
- return NAValue
+ return ZeroValue
}
p := message.NewPrinter(language.English)
- return p.Sprintf("%dMi", v/(client.MegaByte*1_000))
-
+ return p.Sprintf("%d", client.ToMB(v))
}
-// ToResourcesMc prints out request:limit cpu resources.
-func ToResourcesMc(res resources) string {
+func toResourcesMc(res resources) (string, string) {
var v1, v2 int64
if v, ok := res[requestCPU]; ok && v != nil {
v1 = v.MilliValue()
@@ -293,24 +318,31 @@ func ToResourcesMc(res resources) string {
v2 = v.MilliValue()
}
if v1 == 0 && v2 == 0 {
- return NAValue
+ return NAValue, NAValue
}
-
- return toMc(v1) + ":" + toMc(v2)
+ return toMc(v1), toMc(v2)
}
-// ToMc returns a the millicore unit.
-func ToMc(v int64) string {
- p := message.NewPrinter(language.English)
- return p.Sprintf("%dm", v)
+func asMcStr(q *resource.Quantity) string {
+ if q == nil {
+ return ZeroValue
+ }
+ return toMc(q.MilliValue())
}
-// ToMi returns the megabytes unit.
-func ToMi(v int64) string {
- p := message.NewPrinter(language.English)
- return p.Sprintf("%dMi", v)
+func asMiStr(q *resource.Quantity) string {
+ if q == nil {
+ return ZeroValue
+ }
+ return toMi(q.MilliValue())
}
+// // ToMi returns the megabytes unit.
+// func ToMi(v int64) string {
+// p := message.NewPrinter(language.English)
+// return p.Sprintf("%dMi", bytesToMb(v))
+// }
+
func boolPtrToStr(b *bool) string {
if b == nil {
return "false"
diff --git a/internal/render/helpers_test.go b/internal/render/helpers_test.go
index b1e1114f..a438e639 100644
--- a/internal/render/helpers_test.go
+++ b/internal/render/helpers_test.go
@@ -366,13 +366,13 @@ func TestToMc(t *testing.T) {
v int64
e string
}{
- {0, "0m"},
- {2, "2m"},
- {1000, "1,000m"},
+ {0, "0"},
+ {2, "2"},
+ {1_000, "1,000"},
}
for _, u := range uu {
- assert.Equal(t, u.e, ToMc(u.v))
+ assert.Equal(t, u.e, toMc(u.v))
}
}
@@ -381,13 +381,13 @@ func TestToMi(t *testing.T) {
v int64
e string
}{
- {0, "0Mi"},
- {2, "2Mi"},
- {1000, "1,000Mi"},
+ {0, "0"},
+ {2 * client.MegaByte, "2"},
+ {1_000 * client.MegaByte, "1,000"},
}
for _, u := range uu {
- assert.Equal(t, u.e, ToMi(u.v))
+ assert.Equal(t, u.e, toMi(u.v))
}
}
diff --git a/internal/render/node.go b/internal/render/node.go
index 6c215351..b792f4e6 100644
--- a/internal/render/node.go
+++ b/internal/render/node.go
@@ -10,6 +10,7 @@ import (
"github.com/derailed/k9s/internal/client"
"github.com/derailed/tview"
v1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -40,12 +41,16 @@ func (Node) Header(_ string) Header {
HeaderColumn{Name: "INTERNAL-IP", Wide: true},
HeaderColumn{Name: "EXTERNAL-IP", Wide: true},
HeaderColumn{Name: "PODS", Align: tview.AlignRight},
- HeaderColumn{Name: "CPU", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "MEM", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%CPU", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%MEM", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "ACPU", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "AMEM", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "MEM", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU/R", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU/L", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "MEM/R", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "MEM/L", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU/A", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "MEM/A", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "LABELS", Wide: true},
HeaderColumn{Name: "VALID", Wide: true},
HeaderColumn{Name: "AGE", Time: true, Decorator: AgeDecorator},
@@ -73,8 +78,25 @@ func (n Node) Render(o interface{}, ns string, r *Row) error {
iIP, eIP := getIPs(no.Status.Addresses)
iIP, eIP = missing(iIP), missing(eIP)
- c, a, p := gatherNodeMX(&no, oo.MX)
-
+ c, p, a := gatherNodeMX(&no, oo.MX)
+ trc, trm, tlc, tlm := new(resource.Quantity), new(resource.Quantity), new(resource.Quantity), new(resource.Quantity)
+ for _, p := range oo.Pods {
+ rList := podRequests(p.Spec)
+ if rList.Cpu() != nil {
+ trc.Add(*rList.Cpu())
+ }
+ if rList.Memory() != nil {
+ trm.Add(*rList.Memory())
+ }
+ lList := podLimits(p.Spec)
+ if lList.Cpu() != nil {
+ tlc.Add(*lList.Cpu())
+ }
+ if lList.Memory() != nil {
+ tlm.Add(*lList.Memory())
+ }
+ }
+ res := newResources(newResourceList(trc, trm), newResourceList(tlc, tlm))
statuses := make(sort.StringSlice, 10)
status(no.Status, no.Spec.Unschedulable, statuses)
sort.Sort(statuses)
@@ -91,13 +113,17 @@ func (n Node) Render(o interface{}, ns string, r *Row) error {
no.Status.NodeInfo.KernelVersion,
iIP,
eIP,
- strconv.Itoa(oo.PodCount),
- c.cpu,
- c.mem,
- p.cpu,
- p.mem,
- a.cpu,
- a.mem,
+ strconv.Itoa(len(oo.Pods)),
+ strconv.Itoa(p.rCPU()),
+ strconv.Itoa(p.rMEM()),
+ toMc(c.rCPU().MilliValue()),
+ toMi(c.rMEM().Value()),
+ toMcPerc(res.rCPU(), a.rCPU()),
+ toMcPerc(res.lCPU(), a.rCPU()),
+ toMiPerc(res.rMEM(), a.rMEM()),
+ toMiPerc(res.lMEM(), a.rMEM()),
+ toMc(a.rCPU().MilliValue()),
+ toMi(a.rMEM().Value()),
mapToStr(no.Labels),
asStatus(n.diagnose(statuses)),
toAge(no.ObjectMeta.CreationTimestamp),
@@ -136,9 +162,9 @@ func (Node) diagnose(ss []string) error {
// NodeWithMetrics represents a node with its associated metrics.
type NodeWithMetrics struct {
- Raw *unstructured.Unstructured
- MX *mv1beta1.NodeMetrics
- PodCount int
+ Raw *unstructured.Unstructured
+ MX *mv1beta1.NodeMetrics
+ Pods []*v1.Pod
}
// GetObjectKind returns a schema object.
@@ -151,30 +177,21 @@ func (n *NodeWithMetrics) DeepCopyObject() runtime.Object {
return n
}
-func gatherNodeMX(no *v1.Node, mx *mv1beta1.NodeMetrics) (c metric, a metric, p metric) {
- c, a, p = noMetric(), noMetric(), noMetric()
+func gatherNodeMX(no *v1.Node, mx *mv1beta1.NodeMetrics) (resources, percentages, resources) {
+ c, p, a := newResources(nil, nil), newPercentages(), newResources(no.Status.Allocatable, nil)
if mx == nil {
- return
+ return c, p, a
}
- cpu, mem := mx.Usage.Cpu().MilliValue(), client.ToMB(mx.Usage.Memory().Value())
- c = metric{
- cpu: ToMc(cpu),
- mem: ToMi(mem),
+ c[requestCPU], c[requestMEM] = mx.Usage.Cpu(), mx.Usage.Memory()
+ if a.rCPU() != nil {
+ p[requestCPU] = percentMc(c.rCPU(), a.rCPU())
+ }
+ if a.rMEM() != nil {
+ p[requestMEM] = percentMi(c.rMEM(), a.rMEM())
}
- acpu, amem := no.Status.Allocatable.Cpu().MilliValue(), client.ToMB(no.Status.Allocatable.Memory().Value())
- a = metric{
- cpu: ToMc(acpu),
- mem: ToMi(amem),
- }
-
- p = metric{
- cpu: IntToStr(client.ToPercentage(cpu, acpu)),
- mem: IntToStr(client.ToPercentage(mem, amem)),
- }
-
- return
+ return c, p, a
}
func nodeRoles(node *v1.Node, res []string) {
diff --git a/internal/render/node_test.go b/internal/render/node_test.go
index f6154516..de878f2e 100644
--- a/internal/render/node_test.go
+++ b/internal/render/node_test.go
@@ -21,8 +21,8 @@ func TestNodeRender(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "minikube", r.ID)
- e := render.Fields{"minikube", "Ready", "master", "v1.15.2", "4.15.0", "192.168.64.107", "", "0", "10m", "10Mi", "0", "0", "4,000m", "7,874Mi"}
- assert.Equal(t, e, r.Fields[:14])
+ e := render.Fields{"minikube", "Ready", "master", "v1.15.2", "4.15.0", "192.168.64.107", "", "0", "0", "0", "10", "10", "0 (0%)", "0 (0%)", "0 (0%)", "0 (0%)", "4,000", "7,874"}
+ assert.Equal(t, e, r.Fields[:18])
}
func BenchmarkNodeRender(b *testing.B) {
diff --git a/internal/render/pod.go b/internal/render/pod.go
index 05bc0d8f..07755873 100644
--- a/internal/render/pod.go
+++ b/internal/render/pod.go
@@ -16,6 +16,60 @@ import (
mv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
)
+const (
+ requestCPU qualifiedResource = "rcpu"
+ requestMEM = "rmem"
+ limitCPU = "lcpu"
+ limitMEM = "lmem"
+)
+
+type (
+ qualifiedResource string
+ resources map[qualifiedResource]*resource.Quantity
+ percentages map[qualifiedResource]int
+)
+
+func newPercentages() percentages {
+ return make(percentages, 4)
+}
+func (p percentages) rCPU() int {
+ return p[requestCPU]
+}
+func (p percentages) rMEM() int {
+ return p[requestMEM]
+}
+func (p percentages) lCPU() int {
+ return p[limitCPU]
+}
+func (p percentages) lMEM() int {
+ return p[limitMEM]
+}
+
+func newResources(req, lim v1.ResourceList) resources {
+ if lim == nil {
+ lim = v1.ResourceList{}
+ }
+ return resources{
+ requestCPU: req.Cpu(),
+ requestMEM: req.Memory(),
+ limitCPU: lim.Cpu(),
+ limitMEM: lim.Memory(),
+ }
+}
+
+func (r resources) rCPU() *resource.Quantity {
+ return r[requestCPU]
+}
+func (r resources) rMEM() *resource.Quantity {
+ return r[requestMEM]
+}
+func (r resources) lCPU() *resource.Quantity {
+ return r[limitCPU]
+}
+func (r resources) lMEM() *resource.Quantity {
+ return r[limitMEM]
+}
+
// Pod renders a K8s Pod to screen.
type Pod struct{}
@@ -63,13 +117,13 @@ func (Pod) Header(ns string) Header {
HeaderColumn{Name: "READY"},
HeaderColumn{Name: "RESTARTS", Align: tview.AlignRight},
HeaderColumn{Name: "STATUS"},
- HeaderColumn{Name: "CPU(R:L)", Align: tview.AlignRight, MX: true, Wide: true},
- HeaderColumn{Name: "MEM(R:L)", Align: tview.AlignRight, MX: true, Wide: true},
HeaderColumn{Name: "CPU", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "MEM", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "CPU/R:L", Align: tview.AlignRight, Wide: true},
+ HeaderColumn{Name: "MEM/R:L", Align: tview.AlignRight, Wide: true},
HeaderColumn{Name: "%CPU/R", Align: tview.AlignRight, MX: true},
- HeaderColumn{Name: "%MEM/R", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%CPU/L", Align: tview.AlignRight, MX: true},
+ HeaderColumn{Name: "%MEM/R", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%MEM/L", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "IP"},
HeaderColumn{Name: "NODE"},
@@ -104,14 +158,14 @@ func (p Pod) Render(o interface{}, ns string, r *Row) error {
strconv.Itoa(cr) + "/" + strconv.Itoa(len(ss)),
strconv.Itoa(rc),
phase,
- ToResourcesMc(res),
- ToResourcesMi(res),
- c.cpu,
- c.mem,
- perc.cpu,
- perc.mem,
- perc.cpuLim,
- perc.memLim,
+ toMc(c.rCPU().MilliValue()),
+ toMi(c.rMEM().Value()),
+ toMc(res[requestCPU].MilliValue()) + ":" + toMc(res[limitCPU].MilliValue()),
+ toMi(res[requestMEM].Value()) + ":" + toMi(res[limitMEM].Value()),
+ strconv.Itoa(perc.rCPU()),
+ strconv.Itoa(perc.lCPU()),
+ strconv.Itoa(perc.rMEM()),
+ strconv.Itoa(perc.lMEM()),
na(po.Status.PodIP),
na(po.Spec.NodeName),
p.mapQOS(po.Status.QOSClass),
@@ -153,78 +207,48 @@ func (p *PodWithMetrics) DeepCopyObject() runtime.Object {
return p
}
-const (
- requestCPU qualifiedResource = "rcpu"
- requestMEM = "rmem"
- limitCPU = "lcpu"
- limitMEM = "lmem"
-)
-
-type (
- qualifiedResource string
- resources map[qualifiedResource]*resource.Quantity
-)
-
-func (*Pod) gatherPodMX(pod *v1.Pod, mx *mv1beta1.PodMetrics) (c, p metric, r resources) {
- c, p = noMetric(), noMetric()
+func (*Pod) gatherPodMX(pod *v1.Pod, mx *mv1beta1.PodMetrics) (resources, percentages, resources) {
+ rList, lList := podRequests(pod.Spec), podLimits(pod.Spec)
+ r, p := newResources(rList, lList), newPercentages()
if mx == nil {
- return
+ return newResources(nil, nil), p, r
}
- coMetrix := make(map[string]v1.ResourceList)
- for _, cm := range mx.Containers {
- coMetrix[cm.Name] = cm.Usage
+ c := newResources(currentRes(mx), nil)
+ if rList.Cpu() != nil {
+ p[requestCPU] = percentMc(c.rCPU(), rList.Cpu())
}
- cpu, mem := currentRes(mx)
- c = metric{
- cpu: ToMc(cpu.MilliValue()),
- mem: ToMi(client.ToMB(mem.Value())),
+ if rList.Memory() != nil {
+ p[requestMEM] = percentMi(c.rMEM(), rList.Memory())
}
- rc, rm := podRequests(pod.Spec)
- lc, lm := podLimits(pod.Spec)
- r = make(resources, 4)
- r[requestCPU], r[requestMEM] = rc, rm
- r[limitCPU], r[limitMEM] = lc, lm
- p = metric{
- cpu: client.ToPercentageStr(cpu.MilliValue(), rc.MilliValue()),
- mem: client.ToPercentageStr(client.ToMB(mem.Value()), client.ToMB(rm.Value())),
- cpuLim: client.ToPercentageStr(cpu.MilliValue(), lc.MilliValue()),
- memLim: client.ToPercentageStr(client.ToMB(mem.Value()), client.ToMB(lm.Value())),
+ if lList.Cpu() != nil {
+ p[limitCPU] = percentMc(c.rCPU(), lList.Cpu())
+ }
+ if lList.Memory() != nil {
+ p[limitMEM] = percentMi(c.rMEM(), lList.Memory())
}
- return
+ return c, p, r
}
-func containerResources(co v1.Container) (cpu, mem *resource.Quantity) {
- req, limit := co.Resources.Requests, co.Resources.Limits
- switch {
- case len(req) != 0:
- cpu, mem = req.Cpu(), req.Memory()
- case len(limit) != 0:
- cpu, mem = limit.Cpu(), limit.Memory()
+func containerRequests(co *v1.Container) v1.ResourceList {
+ req := co.Resources.Requests
+ if len(req) != 0 {
+ return req
+ }
+ lim := co.Resources.Limits
+ if len(lim) != 0 {
+ return lim
}
- return
+ return newResourceList(nil, nil)
}
-func containerLimits(co v1.Container) (cpu, mem *resource.Quantity) {
- limit := co.Resources.Limits
- if len(limit) == 0 {
- return nil, nil
- }
- return limit.Cpu(), limit.Memory()
-}
-
-func resourceLimits(cc []v1.Container) (cpu, mem *resource.Quantity) {
- cpu, mem = new(resource.Quantity), new(resource.Quantity)
- for _, co := range cc {
+func podLimits(spec v1.PodSpec) v1.ResourceList {
+ cpu, mem := new(resource.Quantity), new(resource.Quantity)
+ for _, co := range spec.Containers {
limit := co.Resources.Limits
- if len(limit) == 0 {
- cpu.Reset()
- mem.Reset()
- break
- }
if limit.Cpu() != nil {
cpu.Add(*limit.Cpu())
}
@@ -232,59 +256,48 @@ func resourceLimits(cc []v1.Container) (cpu, mem *resource.Quantity) {
mem.Add(*limit.Memory())
}
}
- return
+ return newResourceList(cpu, mem)
}
-func podLimits(spec v1.PodSpec) (*resource.Quantity, *resource.Quantity) {
- cc, cm := resourceLimits(spec.Containers)
- ic, im := resourceLimits(spec.InitContainers)
-
- cc.Add(*ic)
- cm.Add(*im)
-
- return cc, cm
+func newResourceList(cpu, mem *resource.Quantity) v1.ResourceList {
+ if cpu == nil {
+ cpu = new(resource.Quantity)
+ }
+ if mem == nil {
+ mem = new(resource.Quantity)
+ }
+ return v1.ResourceList{
+ v1.ResourceCPU: *cpu,
+ v1.ResourceMemory: *mem,
+ }
}
-func podRequests(spec v1.PodSpec) (*resource.Quantity, *resource.Quantity) {
- cc, cm := resourceRequests(spec.Containers)
- ic, im := resourceRequests(spec.InitContainers)
-
- cc.Add(*ic)
- cm.Add(*im)
-
- return cc, cm
-}
-
-func resourceRequests(cc []v1.Container) (cpu, mem *resource.Quantity) {
- cpu, mem = new(resource.Quantity), new(resource.Quantity)
- for _, co := range cc {
- c, m := containerResources(co)
- if c == nil || m == nil {
- cpu.Reset()
- mem.Reset()
- break
+func podRequests(spec v1.PodSpec) v1.ResourceList {
+ cpu, mem := new(resource.Quantity), new(resource.Quantity)
+ for _, co := range spec.Containers {
+ rl := containerRequests(&co)
+ if rl.Cpu() != nil {
+ cpu.Add(*rl.Cpu())
}
- if c != nil {
- cpu.Add(*c)
- }
- if m != nil {
- mem.Add(*m)
+ if rl.Memory() != nil {
+ mem.Add(*rl.Memory())
}
}
-
- return
+ return newResourceList(cpu, mem)
}
-func currentRes(mx *mv1beta1.PodMetrics) (cpu, mem resource.Quantity) {
+func currentRes(mx *mv1beta1.PodMetrics) v1.ResourceList {
+ cpu, mem := new(resource.Quantity), new(resource.Quantity)
if mx == nil {
- return
+ return newResourceList(nil, nil)
}
for _, co := range mx.Containers {
c, m := co.Usage.Cpu(), co.Usage.Memory()
cpu.Add(*c)
mem.Add(*m)
}
- return
+
+ return newResourceList(cpu, mem)
}
func (*Pod) mapQOS(class v1.PodQOSClass) string {
diff --git a/internal/render/pod_test.go b/internal/render/pod_test.go
index 416688bb..5e75ad17 100644
--- a/internal/render/pod_test.go
+++ b/internal/render/pod_test.go
@@ -159,7 +159,7 @@ func TestPodRender(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "default/nginx", r.ID)
- e := render.Fields{"default", "nginx", "●", "1/1", "0", "Running", "100m:n/a", "70Mi:170Mi", "10m", "10Mi", "10", "14", render.NAValue, "5", "172.17.0.6", "minikube", "BE"}
+ e := render.Fields{"default", "nginx", "●", "1/1", "0", "Running", "10", "10", "100:0", "70:170", "10", "0", "14", "5", "172.17.0.6", "minikube", "BE"}
assert.Equal(t, e, r.Fields[:17])
}
@@ -190,7 +190,7 @@ func TestPodInitRender(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "default/nginx", r.ID)
- e := render.Fields{"default", "nginx", "●", "1/1", "0", "Init:0/1", "200m:n/a", "140Mi:340Mi", "10m", "10Mi", "5", "7", render.NAValue, "2", "172.17.0.6", "minikube", "BE"}
+ e := render.Fields{"default", "nginx", "●", "1/1", "0", "Init:0/1", "10", "10", "100:0", "70:170", "10", "0", "14", "5", "172.17.0.6", "minikube", "BE"}
assert.Equal(t, e, r.Fields[:17])
}
diff --git a/internal/render/types.go b/internal/render/types.go
index 049547b7..59e09a55 100644
--- a/internal/render/types.go
+++ b/internal/render/types.go
@@ -43,4 +43,7 @@ const (
// UnsetValue represent an unset value
UnsetValue = ""
+
+ // ZeroValue represents a zero value.
+ ZeroValue = "0"
)
diff --git a/internal/view/app.go b/internal/view/app.go
index 1c754545..00b07c6f 100644
--- a/internal/view/app.go
+++ b/internal/view/app.go
@@ -184,8 +184,8 @@ func (a *App) keyboard(evt *tcell.EventKey) *tcell.EventKey {
func (a *App) bindKeys() {
a.AddActions(ui.KeyActions{
- ui.KeyShiftH: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false),
- ui.KeyShiftC: ui.NewSharedKeyAction("toggleCrumbs", a.toggleCrumbsCmd, false),
+ tcell.KeyCtrlE: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false),
+ tcell.KeyCtrlG: ui.NewSharedKeyAction("toggleCrumbs", a.toggleCrumbsCmd, false),
ui.KeyHelp: ui.NewSharedKeyAction("Help", a.helpCmd, false),
tcell.KeyCtrlA: ui.NewSharedKeyAction("Aliases", a.aliasCmd, false),
tcell.KeyEnter: ui.NewKeyAction("Goto", a.gotoCmd, false),
diff --git a/internal/view/command.go b/internal/view/command.go
index a80f4ce1..06c6e2a8 100644
--- a/internal/view/command.go
+++ b/internal/view/command.go
@@ -240,6 +240,7 @@ func (c *Command) componentFor(gvr, path string, v *MetaViewer) ResourceViewer {
func (c *Command) exec(cmd, gvr string, comp model.Component, clearStack bool) (err error) {
defer func() {
if e := recover(); e != nil {
+ log.Error().Msgf("Something bad happened! %#v", e)
c.app.Content.Dump()
log.Debug().Msgf("History %v", c.app.cmdHistory.List())
diff --git a/internal/view/live_view.go b/internal/view/live_view.go
index d64c93e0..e7470929 100644
--- a/internal/view/live_view.go
+++ b/internal/view/live_view.go
@@ -30,6 +30,7 @@ type LiveView struct {
model model.ResourceViewer
currentRegion, maxRegions int
fullScreen bool
+ managedField bool
cancel context.CancelFunc
}
@@ -132,6 +133,12 @@ func (v *LiveView) bindKeys() {
ui.KeySlash: ui.NewSharedKeyAction("Filter Mode", v.activateCmd, false),
tcell.KeyDelete: ui.NewSharedKeyAction("Erase", v.eraseCmd, false),
})
+
+ if v.title == "YAML" {
+ v.actions.Add(ui.KeyActions{
+ ui.KeyM: ui.NewKeyAction("Toggle ManagedFields", v.toggleManagedCmd, true),
+ })
+ }
}
func (v *LiveView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
@@ -161,12 +168,15 @@ func (v *LiveView) Name() string { return v.title }
// Start starts the view updater.
func (v *LiveView) Start() {
var ctx context.Context
- ctx, v.cancel = context.WithCancel(context.Background())
- ctx = context.WithValue(ctx, internal.KeyFactory, v.app.factory)
+ ctx, v.cancel = context.WithCancel(v.defaultCtx())
v.model.Watch(ctx)
}
+func (v *LiveView) defaultCtx() context.Context {
+ return context.WithValue(context.Background(), internal.KeyFactory, v.app.factory)
+}
+
// Stop terminates the updater.
func (v *LiveView) Stop() {
if v.cancel != nil {
@@ -186,6 +196,17 @@ func (v *LiveView) ExtraHints() map[string]string {
return nil
}
+func (v *LiveView) toggleManagedCmd(evt *tcell.EventKey) *tcell.EventKey {
+ if v.app.InCmdMode() {
+ return evt
+ }
+
+ v.managedField = !v.managedField
+ v.model.SetOptions(v.defaultCtx(), map[string]bool{model.ManagedFieldsOpts: v.managedField})
+
+ return nil
+}
+
func (v *LiveView) toggleFullScreenCmd(evt *tcell.EventKey) *tcell.EventKey {
if v.app.InCmdMode() {
return evt
diff --git a/internal/view/node.go b/internal/view/node.go
index 79a34359..5c902f79 100644
--- a/internal/view/node.go
+++ b/internal/view/node.go
@@ -57,8 +57,6 @@ func (n *Node) bindKeys(aa ui.KeyActions) {
ui.KeyY: ui.NewKeyAction("YAML", n.yamlCmd, true),
ui.KeyShiftC: ui.NewKeyAction("Sort CPU", n.GetTable().SortColCmd(cpuCol, false), false),
ui.KeyShiftM: ui.NewKeyAction("Sort MEM", n.GetTable().SortColCmd(memCol, false), false),
- ui.KeyShiftX: ui.NewKeyAction("Sort CPU%", n.GetTable().SortColCmd("%CPU", false), false),
- ui.KeyShiftZ: ui.NewKeyAction("Sort MEM%", n.GetTable().SortColCmd("%MEM", false), false),
})
}
diff --git a/internal/view/pod.go b/internal/view/pod.go
index ca8aa510..bd20c2b9 100644
--- a/internal/view/pod.go
+++ b/internal/view/pod.go
@@ -358,9 +358,9 @@ func resourceSorters(t *Table) ui.KeyActions {
return ui.KeyActions{
ui.KeyShiftC: ui.NewKeyAction("Sort CPU", t.SortColCmd(cpuCol, false), false),
ui.KeyShiftM: ui.NewKeyAction("Sort MEM", t.SortColCmd(memCol, false), false),
- ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", t.SortColCmd("%CPU/R", false), false),
- ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", t.SortColCmd("%MEM/R", false), false),
- tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", t.SortColCmd("%CPU/L", false), false),
- tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", t.SortColCmd("%MEM/L", false), false),
+ ui.KeyShiftX: ui.NewKeyAction("Sort CPU/R", t.SortColCmd("%CPU/R", false), false),
+ ui.KeyShiftZ: ui.NewKeyAction("Sort MEM/R", t.SortColCmd("%MEM/R", false), false),
+ tcell.KeyCtrlX: ui.NewKeyAction("Sort CPU/L", t.SortColCmd("%CPU/L", false), false),
+ tcell.KeyCtrlQ: ui.NewKeyAction("Sort MEM/L", t.SortColCmd("%MEM/L", false), false),
}
}