resolve conflicts
commit
874226a1b3
|
|
@ -29,6 +29,7 @@ func NewContainer(gvr client.GVR) ResourceViewer {
|
|||
c.SetEnvFn(c.k9sEnv)
|
||||
c.GetTable().SetEnterFn(c.viewLogs)
|
||||
c.GetTable().SetColorerFn(render.Container{}.ColorerFunc())
|
||||
c.GetTable().SetDecorateFn(c.decorateRows)
|
||||
c.SetBindKeysFn(c.bindKeys)
|
||||
c.GetTable().SetDecorateFn(c.portForwardIndicator)
|
||||
|
||||
|
|
@ -48,6 +49,10 @@ func (c *Container) portForwardIndicator(data render.TableData) render.TableData
|
|||
return data
|
||||
}
|
||||
|
||||
func (c *Container) decorateRows(data render.TableData) render.TableData {
|
||||
return decorateCpuMemHeaderRows(c.App(), data)
|
||||
}
|
||||
|
||||
// Name returns the component name.
|
||||
func (c *Container) Name() string { return containerTitle }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/derailed/k9s/internal"
|
||||
|
|
@ -177,3 +178,40 @@ func fqn(ns, n string) string {
|
|||
}
|
||||
return ns + "/" + n
|
||||
}
|
||||
|
||||
func decorateCpuMemHeaderRows(app *App, data render.TableData) render.TableData {
|
||||
for colIndex, header := range data.Header {
|
||||
check := ""
|
||||
if header.Name == "%CPU/L" {
|
||||
check = "cpu"
|
||||
}
|
||||
if header.Name == "%MEM/L" {
|
||||
check = "memory"
|
||||
}
|
||||
if len(check) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, re := range data.RowEvents {
|
||||
if re.Row.Fields[colIndex] == render.NAValue {
|
||||
continue
|
||||
}
|
||||
n, err := strconv.Atoi(re.Row.Fields[colIndex])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if n > 100 {
|
||||
n = 100
|
||||
}
|
||||
severity := app.Config.K9s.Thresholds.LevelFor(check, n)
|
||||
if severity == config.SeverityLow {
|
||||
continue
|
||||
}
|
||||
color := app.Config.K9s.Thresholds.SeverityColor(check, n)
|
||||
if len(color) > 0 {
|
||||
re.Row.Fields[colIndex] = "[" + color + "::b]" + re.Row.Fields[colIndex]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/atotto/clipboard"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -29,6 +31,9 @@ const (
|
|||
flushTimeout = 50 * time.Millisecond
|
||||
)
|
||||
|
||||
// InvalidCharsRX contains invalid filename characters.
|
||||
var invalidPathCharsRX = regexp.MustCompile(`[:/\\]+`)
|
||||
|
||||
// Log represents a generic log viewer.
|
||||
type Log struct {
|
||||
*tview.Flex
|
||||
|
|
@ -180,13 +185,14 @@ func (l *Log) bindKeys() {
|
|||
ui.Key4: ui.NewKeyAction("30m", l.sinceCmd(30*60), true),
|
||||
ui.Key5: ui.NewKeyAction("1h", l.sinceCmd(60*60), true),
|
||||
tcell.KeyEnter: ui.NewSharedKeyAction("Filter", l.filterCmd, false),
|
||||
ui.KeyC: ui.NewKeyAction("Clear", l.clearCmd, true),
|
||||
tcell.KeyCtrlK: ui.NewKeyAction("Clear", l.clearCmd, true),
|
||||
ui.KeyM: ui.NewKeyAction("Mark", l.markCmd, true),
|
||||
ui.KeyS: ui.NewKeyAction("Toggle AutoScroll", l.toggleAutoScrollCmd, true),
|
||||
ui.KeyF: ui.NewKeyAction("Toggle FullScreen", l.toggleFullScreenCmd, true),
|
||||
ui.KeyT: ui.NewKeyAction("Toggle Timestamp", l.toggleTimestampCmd, true),
|
||||
ui.KeyW: ui.NewKeyAction("Toggle Wrap", l.toggleTextWrapCmd, true),
|
||||
tcell.KeyCtrlS: ui.NewKeyAction("Save", l.SaveCmd, true),
|
||||
ui.KeyC: ui.NewKeyAction("Copy", l.cpCmd, true),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -284,18 +290,32 @@ func (l *Log) SaveCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *Log) cpCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
l.app.Flash().Info("Content copied to clipboard...")
|
||||
if err := clipboard.WriteAll(l.logs.GetText(true)); err != nil {
|
||||
l.app.Flash().Err(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sanitizeFilename(name string) string {
|
||||
processedString := invalidPathCharsRX.ReplaceAllString(name, "-")
|
||||
|
||||
return processedString
|
||||
}
|
||||
|
||||
func ensureDir(dir string) error {
|
||||
return os.MkdirAll(dir, 0744)
|
||||
}
|
||||
|
||||
func saveData(cluster, name, data string) (string, error) {
|
||||
dir := filepath.Join(config.K9sDumpDir, cluster)
|
||||
dir := filepath.Join(config.K9sDumpDir, sanitizeFilename(cluster))
|
||||
if err := ensureDir(dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
now := time.Now().UnixNano()
|
||||
fName := fmt.Sprintf("%s-%d.log", strings.Replace(name, "/", "-", -1), now)
|
||||
fName := fmt.Sprintf("%s-%d.log", sanitizeFilename(name), now)
|
||||
|
||||
path := filepath.Join(dir, fName)
|
||||
mod := os.O_CREATE | os.O_WRONLY
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func TestLogAutoScroll(t *testing.T) {
|
|||
v.GetModel().Set(dao.LogItems{dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")})
|
||||
v.GetModel().Notify()
|
||||
|
||||
assert.Equal(t, 14, len(v.Hints()))
|
||||
assert.Equal(t, 15, len(v.Hints()))
|
||||
|
||||
v.toggleAutoScrollCmd(nil)
|
||||
assert.Equal(t, "Autoscroll: Off FullScreen: Off Timestamps: Off Wrap: Off", v.Indicator().GetText(true))
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func (p *Pod) portForwardIndicator(data render.TableData) render.TableData {
|
|||
}
|
||||
}
|
||||
|
||||
return data
|
||||
return decorateCpuMemHeaderRows(p.App(), data)
|
||||
}
|
||||
|
||||
func (p *Pod) bindDangerousKeys(aa ui.KeyActions) {
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ import (
|
|||
func computeFilename(cluster, ns, title, path string) (string, error) {
|
||||
now := time.Now().UnixNano()
|
||||
|
||||
dir := filepath.Join(config.K9sDumpDir, cluster)
|
||||
dir := filepath.Join(config.K9sDumpDir, sanitizeFilename(cluster))
|
||||
if err := ensureDir(dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
name := title + "-" + strings.Replace(path, "/", "-", -1)
|
||||
name := title + "-" + sanitizeFilename(path)
|
||||
if path == "" {
|
||||
name = title
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ func enableRegion(str string) string {
|
|||
}
|
||||
|
||||
func saveYAML(cluster, name, data string) (string, error) {
|
||||
dir := filepath.Join(config.K9sDumpDir, cluster)
|
||||
dir := filepath.Join(config.K9sDumpDir, sanitizeFilename(cluster))
|
||||
if err := ensureDir(dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
now := time.Now().UnixNano()
|
||||
fName := fmt.Sprintf("%s-%d.yml", strings.Replace(name, "/", "-", -1), now)
|
||||
fName := fmt.Sprintf("%s-%d.yml", sanitizeFilename(name), now)
|
||||
|
||||
path := filepath.Join(dir, fName)
|
||||
mod := os.O_CREATE | os.O_WRONLY
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
K9s plugins extend the tool to provide additonal functionality via actions to further help you observe or administer your Kubernetes clusters.
|
||||
|
||||
| Plugin-Name | Description | Available on Views | Shortcut | Kubectl plugin, external dependencies |
|
||||
|-----------------|--------------------------------|--------------------|----------|-------------------------------------------|
|
||||
|-----------------|----------------------------------|--------------------|----------|---------------------------------------------------------------------------------------|
|
||||
| log_stern.yml | View resource logs using stern | pods | Ctrl-l | |
|
||||
| log_jq.yml | View resource logs using jq | pods | Ctrl-j | kubetcl-plugins/kubectl-jq |
|
||||
| job_suspend.yml | Suspends a running cronjob | cronjobs | Ctrl-s | |
|
||||
| dive.yml | Dive image layers | containers | d | [Dive](https://github.com/wagoodman/dive) |
|
||||
| get-all.yml | get all resources in a namespace | all | g | [Krew](https://krew.sigs.k8s.io/), [ketall](https://github.com/corneliusweig/ketall/) |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
plugin:
|
||||
#get all resources in a namespace using the krew get-all plugin
|
||||
get-all:
|
||||
shortCut: g
|
||||
confirm: false
|
||||
description: get-all
|
||||
scopes:
|
||||
- all
|
||||
command: sh
|
||||
background: false
|
||||
args:
|
||||
- -c
|
||||
- "kubectl get-all -n $NAMESPACE | less"
|
||||
Loading…
Reference in New Issue