parent
9427f2a3db
commit
391eed9ea4
|
|
@ -0,0 +1,47 @@
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
|
||||||
|
|
||||||
|
# Release v0.17.5
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated!
|
||||||
|
|
||||||
|
Also if you dig this tool, please consider sponsoring 👆us or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||||
|
|
||||||
|
On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/story/this_is_fine_300.png" align="center" width="500" height="auto"/>
|
||||||
|
|
||||||
|
## Thresholds Reloaded!
|
||||||
|
|
||||||
|
In the previous k9s release, we've introduced the notion of thresholds to provide with an alert mechanism when either the cpu or memory goes high on your clusters. Looking at the current solution, we felt we needed a bit more granularity in the severity levels thanks to [Eldad Assis](https://github.com/eldada) feedback on this one! So here is the new configuration for cluster thresholds. Please keep in mind this feature is still in flux!
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# $HOME/.k9s/config.yml
|
||||||
|
k9s:
|
||||||
|
refreshRate: 2
|
||||||
|
headless: false
|
||||||
|
...
|
||||||
|
# Specify resources thresholds in percent - defaults: critical=90, warn=70
|
||||||
|
thresholds:
|
||||||
|
cpu:
|
||||||
|
critical: 85
|
||||||
|
warn: 75
|
||||||
|
memory:
|
||||||
|
critical: 80
|
||||||
|
warn: 70
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resolved Bugs/Features/PRs
|
||||||
|
|
||||||
|
- [Issue #604](https://github.com/derailed/k9s/issues/604)
|
||||||
|
- [Issue #601](https://github.com/derailed/k9s/issues/601) Thank you [Christian Vent](https://github.com/christian-vent)
|
||||||
|
- [Issue #598](https://github.com/derailed/k9s/issues/598) `Ctrl-l` will now trigger the benchmarking toggle!
|
||||||
|
- [Issue #593](https://github.com/derailed/k9s/issues/593)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
@ -305,6 +305,7 @@ func (a *APIClient) reset() {
|
||||||
|
|
||||||
a.cache = cache.NewLRUExpireCache(cacheSize)
|
a.cache = cache.NewLRUExpireCache(cacheSize)
|
||||||
a.client, a.dClient, a.nsClient, a.mxsClient = nil, nil, nil, nil
|
a.client, a.dClient, a.nsClient, a.mxsClient = nil, nil, nil, nil
|
||||||
|
a.cachedClient = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APIClient) supportsMetricsResources() (supported bool) {
|
func (a *APIClient) supportsMetricsResources() (supported bool) {
|
||||||
|
|
|
||||||
|
|
@ -299,17 +299,11 @@ var expectedConfig = `k9s:
|
||||||
active: ctx
|
active: ctx
|
||||||
thresholds:
|
thresholds:
|
||||||
cpu:
|
cpu:
|
||||||
defcon:
|
critical: 90
|
||||||
- 90
|
warn: 70
|
||||||
- 80
|
|
||||||
- 75
|
|
||||||
- 70
|
|
||||||
memory:
|
memory:
|
||||||
defcon:
|
critical: 90
|
||||||
- 90
|
warn: 70
|
||||||
- 80
|
|
||||||
- 75
|
|
||||||
- 70
|
|
||||||
`
|
`
|
||||||
|
|
||||||
var resetConfig = `k9s:
|
var resetConfig = `k9s:
|
||||||
|
|
@ -331,15 +325,9 @@ var resetConfig = `k9s:
|
||||||
active: po
|
active: po
|
||||||
thresholds:
|
thresholds:
|
||||||
cpu:
|
cpu:
|
||||||
defcon:
|
critical: 90
|
||||||
- 90
|
warn: 70
|
||||||
- 80
|
|
||||||
- 75
|
|
||||||
- 70
|
|
||||||
memory:
|
memory:
|
||||||
defcon:
|
critical: 90
|
||||||
- 90
|
warn: 70
|
||||||
- 80
|
|
||||||
- 75
|
|
||||||
- 70
|
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,63 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/client"
|
"github.com/derailed/k9s/internal/client"
|
||||||
"github.com/derailed/k9s/internal/render"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefCon1 tracks high severity.
|
// SeverityLow tracks low severity.
|
||||||
DefCon1 DefConLevel = iota + 1
|
SeverityLow SeverityLevel = iota
|
||||||
|
|
||||||
// DefCon2 tracks warn level.
|
// SeverityMedium tracks medium severity level.
|
||||||
DefCon2
|
SeverityMedium
|
||||||
|
|
||||||
// DefCon3 tracks medium level.
|
// SeverityHigh tracks high severity level.
|
||||||
DefCon3
|
SeverityHigh
|
||||||
|
|
||||||
// DefCon4 tracks low level.
|
|
||||||
DefCon4
|
|
||||||
|
|
||||||
// DefCon5 tracks all cool.
|
|
||||||
DefCon5
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefConLevel tracks defcon severity.
|
// SeverityLevel tracks severity levels.
|
||||||
type DefConLevel int
|
type SeverityLevel int
|
||||||
|
|
||||||
// DefCon tracks a resource alert level.
|
// Severity tracks a resource severity levels.
|
||||||
type DefCon struct {
|
type Severity struct {
|
||||||
Levels []int `yaml:"defcon,omitempty"`
|
Critical int `yaml:"critical"`
|
||||||
|
Warn int `yaml:"warn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDefCon returns a new instance.
|
// NewSeverity returns a new instance.
|
||||||
func NewDefCon() *DefCon {
|
func NewSeverity() *Severity {
|
||||||
return &DefCon{Levels: []int{90, 80, 75, 70}}
|
return &Severity{
|
||||||
|
Critical: 90,
|
||||||
|
Warn: 70,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate checks all thresholds and make sure we're cool. If not use defaults.
|
// Validate checks all thresholds and make sure we're cool. If not use defaults.
|
||||||
func (d *DefCon) Validate() {
|
func (s *Severity) Validate() {
|
||||||
norm := NewDefCon()
|
norm := NewSeverity()
|
||||||
if len(d.Levels) < 4 {
|
if !validateRange(s.Warn) {
|
||||||
d.Levels = norm.Levels
|
s.Warn = norm.Warn
|
||||||
return
|
|
||||||
}
|
|
||||||
for i, level := range d.Levels {
|
|
||||||
if !d.isValidRange(level) {
|
|
||||||
d.Levels[i] = norm.Levels[i]
|
|
||||||
}
|
}
|
||||||
|
if !validateRange(s.Critical) {
|
||||||
|
s.Critical = norm.Critical
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns defcon settings a string.
|
func validateRange(v int) bool {
|
||||||
func (d *DefCon) String() string {
|
if v <= 0 || v > 100 {
|
||||||
ss := make([]string, len(d.Levels))
|
|
||||||
for i := 0; i < len(d.Levels); i++ {
|
|
||||||
ss[i] = render.PrintPerc(d.Levels[i])
|
|
||||||
}
|
|
||||||
return strings.Join(ss, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DefCon) isValidRange(v int) bool {
|
|
||||||
if v < 0 || v > 100 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Threshold tracks threshold to alert user when excided.
|
// Threshold tracks threshold to alert user when excided.
|
||||||
type Threshold map[string]*DefCon
|
type Threshold map[string]*Severity
|
||||||
|
|
||||||
// NewThreshold returns a new threshold.
|
// NewThreshold returns a new threshold.
|
||||||
func NewThreshold() Threshold {
|
func NewThreshold() Threshold {
|
||||||
return Threshold{
|
return Threshold{
|
||||||
"cpu": NewDefCon(),
|
"cpu": NewSeverity(),
|
||||||
"memory": NewDefCon(),
|
"memory": NewSeverity(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,7 +66,7 @@ func (t Threshold) Validate(c client.Connection, ks KubeSettings) {
|
||||||
for _, k := range []string{"cpu", "memory"} {
|
for _, k := range []string{"cpu", "memory"} {
|
||||||
v, ok := t[k]
|
v, ok := t[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
t[k] = NewDefCon()
|
t[k] = NewSeverity()
|
||||||
} else {
|
} else {
|
||||||
v.Validate()
|
v.Validate()
|
||||||
}
|
}
|
||||||
|
|
@ -92,48 +74,29 @@ func (t Threshold) Validate(c client.Connection, ks KubeSettings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefConFor returns a defcon level for the current state.
|
// DefConFor returns a defcon level for the current state.
|
||||||
func (t Threshold) DefConFor(k string, v int) DefConLevel {
|
func (t Threshold) LevelFor(k string, v int) SeverityLevel {
|
||||||
dc, ok := t[k]
|
s, ok := t[k]
|
||||||
if !ok || v < 0 || v > 100 {
|
if !ok || v < 0 || v > 100 {
|
||||||
return DefCon5
|
return SeverityLow
|
||||||
}
|
}
|
||||||
for i, l := range dc.Levels {
|
if v >= s.Critical {
|
||||||
if v >= l {
|
return SeverityHigh
|
||||||
return dcLevelFor(i)
|
|
||||||
}
|
}
|
||||||
|
if v >= s.Warn {
|
||||||
|
return SeverityMedium
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefCon5
|
return SeverityLow
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefConColorFor returns an defcon level associated level.
|
// DefConColorFor returns an defcon level associated level.
|
||||||
func (t *Threshold) DefConColorFor(k string, v int) string {
|
func (t *Threshold) SeverityColor(k string, v int) string {
|
||||||
switch t.DefConFor(k, v) {
|
switch t.LevelFor(k, v) {
|
||||||
case DefCon1:
|
case SeverityHigh:
|
||||||
return "red"
|
return "red"
|
||||||
case DefCon2:
|
case SeverityMedium:
|
||||||
return "orangered"
|
return "orangered"
|
||||||
case DefCon3:
|
|
||||||
return "orange"
|
|
||||||
default:
|
default:
|
||||||
return "green"
|
return "green"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Helpers...
|
|
||||||
|
|
||||||
func dcLevelFor(l int) DefConLevel {
|
|
||||||
switch l {
|
|
||||||
case 0:
|
|
||||||
return DefCon1
|
|
||||||
case 1:
|
|
||||||
return DefCon2
|
|
||||||
case 2:
|
|
||||||
return DefCon3
|
|
||||||
case 3:
|
|
||||||
return DefCon4
|
|
||||||
default:
|
|
||||||
return DefCon5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,25 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDefConValidate(t *testing.T) {
|
func TestSeverityValidate(t *testing.T) {
|
||||||
uu := map[string]struct {
|
uu := map[string]struct {
|
||||||
d, e *config.DefCon
|
d, e *config.Severity
|
||||||
}{
|
}{
|
||||||
"default": {
|
"default": {
|
||||||
d: config.NewDefCon(),
|
d: config.NewSeverity(),
|
||||||
e: config.NewDefCon(),
|
e: config.NewSeverity(),
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
d: &config.DefCon{Levels: []int{10}},
|
d: &config.Severity{Warn: 10},
|
||||||
e: config.NewDefCon(),
|
e: &config.Severity{Warn: 10, Critical: 90},
|
||||||
},
|
},
|
||||||
"negative": {
|
"negative": {
|
||||||
d: &config.DefCon{Levels: []int{-1, 10, 10, 10}},
|
d: &config.Severity{Warn: -1},
|
||||||
e: &config.DefCon{Levels: []int{90, 10, 10, 10}},
|
e: config.NewSeverity(),
|
||||||
},
|
},
|
||||||
"out-of-range": {
|
"out-of-range": {
|
||||||
d: &config.DefCon{Levels: []int{150, 200, 10, 300}},
|
d: &config.Severity{Warn: 150},
|
||||||
e: &config.DefCon{Levels: []int{90, 80, 10, 70}},
|
e: config.NewSeverity(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,41 +38,41 @@ func TestDefConValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefConFor(t *testing.T) {
|
func TestLevelFor(t *testing.T) {
|
||||||
uu := map[string]struct {
|
uu := map[string]struct {
|
||||||
k string
|
k string
|
||||||
v int
|
v int
|
||||||
e config.DefConLevel
|
e config.SeverityLevel
|
||||||
}{
|
}{
|
||||||
"normal": {
|
"normal": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 0,
|
v: 0,
|
||||||
e: config.DefCon5,
|
e: config.SeverityLow,
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 71,
|
v: 71,
|
||||||
e: config.DefCon4,
|
e: config.SeverityMedium,
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 75,
|
v: 75,
|
||||||
e: config.DefCon3,
|
e: config.SeverityMedium,
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 80,
|
v: 80,
|
||||||
e: config.DefCon2,
|
e: config.SeverityMedium,
|
||||||
},
|
},
|
||||||
"1": {
|
"1": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 100,
|
v: 100,
|
||||||
e: config.DefCon1,
|
e: config.SeverityHigh,
|
||||||
},
|
},
|
||||||
"over": {
|
"over": {
|
||||||
k: "cpu",
|
k: "cpu",
|
||||||
v: 150,
|
v: 150,
|
||||||
e: config.DefCon5,
|
e: config.SeverityLow,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ func TestDefConFor(t *testing.T) {
|
||||||
for k := range uu {
|
for k := range uu {
|
||||||
u := uu[k]
|
u := uu[k]
|
||||||
t.Run(k, func(t *testing.T) {
|
t.Run(k, func(t *testing.T) {
|
||||||
assert.Equal(t, u.e, o.DefConFor(u.k, u.v))
|
assert.Equal(t, u.e, o.LevelFor(u.k, u.v))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var res []runtime.Object
|
res := make([]runtime.Object, 0, len(oo))
|
||||||
for _, o := range oo {
|
for _, o := range oo {
|
||||||
u, ok := o.(*unstructured.Unstructured)
|
u, ok := o.(*unstructured.Unstructured)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ func (b *Browser) editCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
}
|
}
|
||||||
ns, n := client.Namespaced(path)
|
ns, n := client.Namespaced(path)
|
||||||
|
|
||||||
if ok, err := b.app.Conn().CanI(ns, b.GVR().String(), []string{"edit"}); !ok || err != nil {
|
if ok, err := b.app.Conn().CanI(ns, b.GVR().String(), []string{"patch"}); !ok || err != nil {
|
||||||
b.App().Flash().Err(fmt.Errorf("Current user can't edit resource %s", b.GVR()))
|
b.App().Flash().Err(fmt.Errorf("Current user can't edit resource %s", b.GVR()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,16 +72,16 @@ func (c *ClusterInfo) infoCell(t string) *tview.TableCell {
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClusterInfoUpdated notifies the cluster meta was updated.
|
|
||||||
func (c *ClusterInfo) ClusterInfoUpdated(data model.ClusterMeta) {
|
|
||||||
c.ClusterInfoChanged(data, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClusterInfo) setCell(row int, s string) int {
|
func (c *ClusterInfo) setCell(row int, s string) int {
|
||||||
c.GetCell(row, 1).SetText(s)
|
c.GetCell(row, 1).SetText(s)
|
||||||
return row + 1
|
return row + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClusterInfoUpdated notifies the cluster meta was updated.
|
||||||
|
func (c *ClusterInfo) ClusterInfoUpdated(data model.ClusterMeta) {
|
||||||
|
c.ClusterInfoChanged(data, data)
|
||||||
|
}
|
||||||
|
|
||||||
// ClusterInfoChanged notifies the cluster meta was changed.
|
// ClusterInfoChanged notifies the cluster meta was changed.
|
||||||
func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) {
|
func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) {
|
||||||
c.app.QueueUpdateDraw(func() {
|
c.app.QueueUpdateDraw(func() {
|
||||||
|
|
@ -101,20 +101,18 @@ func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const defconFmt = "Cluster <%s> at DEFCON %d"
|
const defconFmt = "%s %s level!"
|
||||||
|
|
||||||
func (c *ClusterInfo) setDefCon(cpu, mem int) {
|
func (c *ClusterInfo) setDefCon(cpu, mem int) {
|
||||||
var set bool
|
var set bool
|
||||||
dc := c.app.Config.K9s.Thresholds.DefConFor("cpu", cpu)
|
l := c.app.Config.K9s.Thresholds.LevelFor("cpu", cpu)
|
||||||
if dc < config.DefCon5 {
|
if l > config.SeverityLow {
|
||||||
l := flashFromDefCon(dc)
|
c.app.Status(flashLevel(l), fmt.Sprintf(defconFmt, flashMessage(l), "CPU"))
|
||||||
c.app.Status(l, fmt.Sprintf(defconFmt, "cpu", int(dc)))
|
|
||||||
set = true
|
set = true
|
||||||
}
|
}
|
||||||
dc = c.app.Config.K9s.Thresholds.DefConFor("memory", mem)
|
l = c.app.Config.K9s.Thresholds.LevelFor("memory", mem)
|
||||||
if dc < config.DefCon5 {
|
if l > config.SeverityLow {
|
||||||
l := flashFromDefCon(dc)
|
c.app.Status(flashLevel(l), fmt.Sprintf(defconFmt, flashMessage(l), "Memory"))
|
||||||
c.app.Status(l, fmt.Sprintf(defconFmt, "mem", int(dc)))
|
|
||||||
set = true
|
set = true
|
||||||
}
|
}
|
||||||
if !set {
|
if !set {
|
||||||
|
|
@ -131,13 +129,27 @@ func (c *ClusterInfo) updateStyle() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func flashFromDefCon(l config.DefConLevel) model.FlashLevel {
|
// ----------------------------------------------------------------------------
|
||||||
|
// Helpers...
|
||||||
|
|
||||||
|
func flashLevel(l config.SeverityLevel) model.FlashLevel {
|
||||||
switch l {
|
switch l {
|
||||||
case config.DefCon1:
|
case config.SeverityHigh:
|
||||||
return model.FlashErr
|
return model.FlashErr
|
||||||
case config.DefCon2, config.DefCon3:
|
case config.SeverityMedium:
|
||||||
return model.FlashWarn
|
return model.FlashWarn
|
||||||
default:
|
default:
|
||||||
return model.FlashInfo
|
return model.FlashInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flashMessage(l config.SeverityLevel) string {
|
||||||
|
switch l {
|
||||||
|
case config.SeverityHigh:
|
||||||
|
return "Critical"
|
||||||
|
case config.SeverityMedium:
|
||||||
|
return "Warning"
|
||||||
|
default:
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (p *PortForward) portForwardContext(ctx context.Context) context.Context {
|
||||||
func (p *PortForward) bindKeys(aa ui.KeyActions) {
|
func (p *PortForward) bindKeys(aa ui.KeyActions) {
|
||||||
aa.Add(ui.KeyActions{
|
aa.Add(ui.KeyActions{
|
||||||
tcell.KeyEnter: ui.NewKeyAction("View Benchmarks", p.showBenchCmd, true),
|
tcell.KeyEnter: ui.NewKeyAction("View Benchmarks", p.showBenchCmd, true),
|
||||||
tcell.KeyCtrlB: ui.NewKeyAction("Bench Run/Stop", p.toggleBenchCmd, true),
|
tcell.KeyCtrlL: ui.NewKeyAction("Benchmark Run/Stop", p.toggleBenchCmd, true),
|
||||||
tcell.KeyCtrlD: ui.NewKeyAction("Delete", p.deleteCmd, true),
|
tcell.KeyCtrlD: ui.NewKeyAction("Delete", p.deleteCmd, true),
|
||||||
ui.KeyShiftP: ui.NewKeyAction("Sort Ports", p.GetTable().SortColCmd("PORTS", true), false),
|
ui.KeyShiftP: ui.NewKeyAction("Sort Ports", p.GetTable().SortColCmd("PORTS", true), false),
|
||||||
ui.KeyShiftU: ui.NewKeyAction("Sort URL", p.GetTable().SortColCmd("URL", true), false),
|
ui.KeyShiftU: ui.NewKeyAction("Sort URL", p.GetTable().SortColCmd("URL", true), false),
|
||||||
|
|
@ -159,7 +159,7 @@ func (p *Pulse) PulseChanged(c *health.Check) {
|
||||||
perc := client.ToPercentage(c.Tally(health.S1), c.Tally(health.S2))
|
perc := client.ToPercentage(c.Tally(health.S1), c.Tally(health.S2))
|
||||||
v.SetLegend(fmt.Sprintf(cpuFmt,
|
v.SetLegend(fmt.Sprintf(cpuFmt,
|
||||||
strings.Title(gvr.R()),
|
strings.Title(gvr.R()),
|
||||||
p.app.Config.K9s.Thresholds.DefConColorFor("cpu", perc),
|
p.app.Config.K9s.Thresholds.SeverityColor("cpu", perc),
|
||||||
render.PrintPerc(perc),
|
render.PrintPerc(perc),
|
||||||
nn[0],
|
nn[0],
|
||||||
render.AsThousands(c.Tally(health.S1)),
|
render.AsThousands(c.Tally(health.S1)),
|
||||||
|
|
@ -170,7 +170,7 @@ func (p *Pulse) PulseChanged(c *health.Check) {
|
||||||
perc := client.ToPercentage(c.Tally(health.S1), c.Tally(health.S2))
|
perc := client.ToPercentage(c.Tally(health.S1), c.Tally(health.S2))
|
||||||
v.SetLegend(fmt.Sprintf(memFmt,
|
v.SetLegend(fmt.Sprintf(memFmt,
|
||||||
strings.Title(gvr.R()),
|
strings.Title(gvr.R()),
|
||||||
p.app.Config.K9s.Thresholds.DefConColorFor("memory", perc),
|
p.app.Config.K9s.Thresholds.SeverityColor("memory", perc),
|
||||||
render.PrintPerc(perc),
|
render.PrintPerc(perc),
|
||||||
nn[0],
|
nn[0],
|
||||||
render.AsThousands(c.Tally(health.S1)),
|
render.AsThousands(c.Tally(health.S1)),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue