mine
derailed 2021-04-29 10:51:56 -06:00
parent 679243d829
commit d38efba564
35 changed files with 130 additions and 86 deletions

View File

@ -289,6 +289,8 @@ var expectedConfig = `k9s:
nodeShell: false
shellPod:
image: busybox:1.31
command: []
args: []
namespace: default
limits:
cpu: 100m
@ -309,6 +311,8 @@ var expectedConfig = `k9s:
nodeShell: false
shellPod:
image: busybox:1.31
command: []
args: []
namespace: default
limits:
cpu: 100m
@ -329,6 +333,8 @@ var expectedConfig = `k9s:
nodeShell: false
shellPod:
image: busybox:1.31
command: []
args: []
namespace: default
limits:
cpu: 100m
@ -373,6 +379,8 @@ var resetConfig = `k9s:
nodeShell: false
shellPod:
image: busybox:1.31
command: []
args: []
namespace: default
limits:
cpu: 100m

View File

@ -12,9 +12,11 @@ type Limits map[v1.ResourceName]string
// ShellPod represents k9s shell configuration.
type ShellPod struct {
Image string `json:"Image"`
Namespace string `json:"namespace"`
Limits Limits `json:"resources,omitempty"`
Image string `json:"image"`
Command []string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Namespace string `json:"namespace"`
Limits Limits `json:"resources,omitempty"`
}
// NewShellPod returns a new instance.

View File

@ -221,7 +221,7 @@ func (c Color) Color() tcell.Color {
return tcell.ColorDefault
}
return tcell.GetColor(string(c))
return tcell.GetColor(string(c)).TrueColor()
}
// Colors converts series string colors to colors.

View File

@ -1,7 +1,6 @@
package config_test
import (
"fmt"
"testing"
"github.com/derailed/k9s/internal/config"
@ -13,7 +12,7 @@ import (
func TestColor(t *testing.T) {
uu := map[string]tcell.Color{
"blah": tcell.ColorDefault,
"blue": tcell.ColorBlue,
"blue": tcell.ColorBlue.TrueColor(),
"#ffffff": tcell.NewHexColor(16777215),
"#ff0000": tcell.NewHexColor(16711680),
}
@ -21,7 +20,6 @@ func TestColor(t *testing.T) {
for k := range uu {
c, u := k, uu[k]
t.Run(k, func(t *testing.T) {
fmt.Printf("%#v\n", config.NewColor(c).Color().Hex())
assert.Equal(t, u, config.NewColor(c).Color())
})
}
@ -32,12 +30,12 @@ func TestSkinNone(t *testing.T) {
assert.Nil(t, s.Load("testdata/empty_skin.yml"))
s.Update()
assert.Equal(t, "cadetblue", s.Body().FgColor.String())
assert.Equal(t, "black", s.Body().BgColor.String())
assert.Equal(t, "black", s.Table().BgColor.String())
assert.Equal(t, tcell.ColorCadetBlue, s.FgColor())
assert.Equal(t, tcell.ColorBlack, s.BgColor())
assert.Equal(t, tcell.ColorBlack, tview.Styles.PrimitiveBackgroundColor)
assert.Equal(t, "#5f9ea0", s.Body().FgColor.String())
assert.Equal(t, "#000000", s.Body().BgColor.String())
assert.Equal(t, "#000000", s.Table().BgColor.String())
assert.Equal(t, tcell.ColorCadetBlue.TrueColor(), s.FgColor())
assert.Equal(t, tcell.ColorBlack.TrueColor(), s.BgColor())
assert.Equal(t, tcell.ColorBlack.TrueColor(), tview.Styles.PrimitiveBackgroundColor)
}
func TestSkin(t *testing.T) {
@ -45,12 +43,12 @@ func TestSkin(t *testing.T) {
assert.Nil(t, s.Load("testdata/black_and_wtf.yml"))
s.Update()
assert.Equal(t, "white", s.Body().FgColor.String())
assert.Equal(t, "black", s.Body().BgColor.String())
assert.Equal(t, "black", s.Table().BgColor.String())
assert.Equal(t, tcell.ColorWhite, s.FgColor())
assert.Equal(t, tcell.ColorBlack, s.BgColor())
assert.Equal(t, tcell.ColorBlack, tview.Styles.PrimitiveBackgroundColor)
assert.Equal(t, "#ffffff", s.Body().FgColor.String())
assert.Equal(t, "#000000", s.Body().BgColor.String())
assert.Equal(t, "#000000", s.Table().BgColor.String())
assert.Equal(t, tcell.ColorWhite.TrueColor(), s.FgColor())
assert.Equal(t, tcell.ColorBlack.TrueColor(), s.BgColor())
assert.Equal(t, tcell.ColorBlack.TrueColor(), tview.Styles.PrimitiveBackgroundColor)
}
func TestSkinNotExits(t *testing.T) {

View File

@ -91,6 +91,7 @@ func (t Threshold) LevelFor(k string, v int) SeverityLevel {
// SeverityColor returns an defcon level associated level.
func (t *Threshold) SeverityColor(k string, v int) string {
// nolint:exhaustive
switch t.LevelFor(k, v) {
case SeverityHigh:
return "red"

View File

@ -85,7 +85,7 @@ func (g *Generic) ToYAML(path string, showManaged bool) (string, error) {
raw, err := ToYAML(o, showManaged)
if err != nil {
return "", fmt.Errorf("unable to marshal resource %s", err)
return "", fmt.Errorf("unable to marshal resource %w", err)
}
return raw, nil
}

View File

@ -204,7 +204,7 @@ func createSystemEndpoint(gateway, namespace string) (string, error) {
gatewayURL, err := url.Parse(gateway)
if err != nil {
return "", fmt.Errorf("invalid gateway URL: %s", err.Error())
return "", fmt.Errorf("invalid gateway URL: %w", err)
}
gatewayURL.Path = path.Join(gatewayURL.Path, systemPath)
if len(namespace) > 0 {

View File

@ -47,7 +47,7 @@ func (r *Resource) ToYAML(path string, showManaged bool) (string, error) {
raw, err := ToYAML(o, showManaged)
if err != nil {
return "", fmt.Errorf("unable to marshal resource %s", err)
return "", fmt.Errorf("unable to marshal resource %w", err)
}
return raw, nil
}

View File

@ -48,7 +48,7 @@ func (h *PulseHealth) List(ctx context.Context, ns string) ([]runtime.Object, er
mm, err := h.checkMetrics(ctx)
if err != nil {
return hh, nil
return hh, err
}
for _, m := range mm {
hh = append(hh, m)

View File

@ -39,6 +39,7 @@ func DefaultColorer(ns string, h Header, re RowEvent) tcell.Color {
return ErrColor
}
// nolint:exhaustive
switch re.Kind {
case EventAdd:
return AddColor

View File

@ -175,6 +175,7 @@ func toMetricsV2b2(specs []autoscalingv2beta2.MetricSpec, statuses []autoscaling
for i, spec := range specs {
current := "<unknown>"
// nolint:exhaustive
switch spec.Type {
case autoscalingv2beta2.ExternalMetricSourceType:
list = append(list, externalMetricsV2b2(i, spec, statuses))
@ -211,6 +212,7 @@ func toMetricsV2b2(specs []autoscalingv2beta2.MetricSpec, statuses []autoscaling
func checkHPAType(i int, spec autoscalingv2beta1.MetricSpec, statuses []autoscalingv2beta1.MetricStatus) string {
current := "<unknown>"
// nolint:exhaustive
switch spec.Type {
case autoscalingv2beta1.ExternalMetricSourceType:
return externalMetricsV2b1(i, spec, statuses)
@ -235,7 +237,7 @@ func externalMetricsV2b2(i int, spec autoscalingv2beta2.MetricSpec, statuses []a
current := "<unknown>"
if spec.External.Target.AverageValue != nil {
if len(statuses) > i && statuses[i].External != nil && &statuses[i].External.Current.AverageValue != nil {
if len(statuses) > i && statuses[i].External != nil && statuses[i].External.Current.AverageValue != nil {
current = statuses[i].External.Current.AverageValue.String()
}
return current + "/" + spec.External.Target.AverageValue.String() + " (avg)"
@ -272,7 +274,7 @@ func resourceMetricsV2b2(i int, spec autoscalingv2beta2.MetricSpec, statuses []a
func externalMetricsV2b1(i int, spec autoscalingv2beta1.MetricSpec, statuses []autoscalingv2beta1.MetricStatus) string {
current := "<unknown>"
if spec.External.TargetAverageValue != nil {
if len(statuses) > i && statuses[i].External != nil && &statuses[i].External.CurrentAverageValue != nil {
if len(statuses) > i && statuses[i].External != nil && statuses[i].External.CurrentAverageValue != nil {
current = statuses[i].External.CurrentAverageValue.String()
}
return current + "/" + spec.External.TargetAverageValue.String() + " (avg)"

View File

@ -188,6 +188,7 @@ func nodeRoles(node *v1.Node, res []string) {
func getIPs(addrs []v1.NodeAddress) (iIP, eIP string) {
for _, a := range addrs {
// nolint:exhaustive
switch a.Type {
case v1.NodeExternalIP:
eIP = a.Address

View File

@ -257,6 +257,7 @@ func currentRes(mx *mv1beta1.PodMetrics) (resource.Quantity, resource.Quantity)
}
func (*Pod) mapQOS(class v1.PodQOSClass) string {
// nolint:exhaustive
switch class {
case v1.PodQOSGuaranteed:
return "GA"

View File

@ -34,7 +34,7 @@ var _ os.FileInfo = fileInfo{}
func (f fileInfo) Name() string { return "bob" }
func (f fileInfo) Size() int64 { return 100 }
func (f fileInfo) Mode() os.FileMode { return os.FileMode(644) }
func (f fileInfo) Mode() os.FileMode { return os.FileMode(0644) }
func (f fileInfo) ModTime() time.Time { return testTime() }
func (f fileInfo) IsDir() bool { return false }
func (f fileInfo) Sys() interface{} { return nil }

View File

@ -64,6 +64,7 @@ func (c *Component) SetLegend(l string) {
// InputHandler returns the handler for this primitive.
func (c *Component) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return c.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
// nolint:exhaustive
switch key := event.Key(); key {
case tcell.KeyEnter:
case tcell.KeyBacktab, tcell.KeyTab:

View File

@ -164,6 +164,7 @@ func computeDelta(d1, d2 int64) delta {
func printDelta(sc tcell.Screen, d delta, o image.Point, s tcell.Style) {
s = s.Dim(false)
// nolint:exhaustive
switch d {
case DeltaLess:
sc.SetContent(o.X-1, o.Y+1, '↓', nil, s)

View File

@ -24,6 +24,6 @@ func TestConfiguratorRefreshStyle(t *testing.T) {
cfg.RefreshStyles("")
assert.True(t, cfg.HasSkin())
assert.Equal(t, tcell.ColorGhostWhite, render.StdColor)
assert.Equal(t, tcell.ColorWhiteSmoke, render.ErrColor)
assert.Equal(t, tcell.ColorGhostWhite.TrueColor(), render.StdColor)
assert.Equal(t, tcell.ColorWhiteSmoke.TrueColor(), render.ErrColor)
}

View File

@ -23,7 +23,7 @@ func TestNewCrumbs(t *testing.T) {
v.StackPushed(makeComponent("c2"))
v.StackPushed(makeComponent("c3"))
assert.Equal(t, "[black:aqua:b] <c1> [-:black:-] [black:aqua:b] <c2> [-:black:-] [black:orange:b] <c3> [-:black:-] \n", v.GetText(false))
assert.Equal(t, "[#000000:#00ffff:b] <c1> [-:#000000:-] [#000000:#00ffff:b] <c2> [-:#000000:-] [#000000:#ffa500:b] <c3> [-:#000000:-] \n", v.GetText(false))
}
// Helpers...

View File

@ -85,6 +85,7 @@ func (f *Flash) flashEmoji(l model.FlashLevel) string {
if f.app.Config.K9s.NoIcons {
return ""
}
// nolint:exhaustive
switch l {
case model.FlashWarn:
return emoDoh
@ -98,6 +99,7 @@ func (f *Flash) flashEmoji(l model.FlashLevel) string {
// Helpers...
func flashColor(l model.FlashLevel) tcell.Color {
// nolint:exhaustive
switch l {
case model.FlashWarn:
return tcell.ColorOrange

View File

@ -12,7 +12,7 @@ func TestNewLogoView(t *testing.T) {
v := ui.NewLogo(config.NewStyles())
v.Reset()
const elogo = "[orange::b] ____ __.________ \n[orange::b]| |/ _/ __ \\______\n[orange::b]| < \\____ / ___/\n[orange::b]| | \\ / /\\___ \\ \n[orange::b]|____|__ \\ /____//____ >\n[orange::b] \\/ \\/ \n"
const elogo = "[#ffa500::b] ____ __.________ \n[#ffa500::b]| |/ _/ __ \\______\n[#ffa500::b]| < \\____ / ___/\n[#ffa500::b]| | \\ / /\\___ \\ \n[#ffa500::b]|____|__ \\ /____//____ >\n[#ffa500::b] \\/ \\/ \n"
assert.Equal(t, elogo, v.Logo().GetText(false))
assert.Equal(t, "", v.Status().GetText(false))
}
@ -22,17 +22,17 @@ func TestLogoStatus(t *testing.T) {
logo, msg, e string
}{
"info": {
"[green::b] ____ __.________ \n[green::b]| |/ _/ __ \\______\n[green::b]| < \\____ / ___/\n[green::b]| | \\ / /\\___ \\ \n[green::b]|____|__ \\ /____//____ >\n[green::b] \\/ \\/ \n",
"[#008000::b] ____ __.________ \n[#008000::b]| |/ _/ __ \\______\n[#008000::b]| < \\____ / ___/\n[#008000::b]| | \\ / /\\___ \\ \n[#008000::b]|____|__ \\ /____//____ >\n[#008000::b] \\/ \\/ \n",
"blee",
"[white::b]blee\n",
},
"warn": {
"[mediumvioletred::b] ____ __.________ \n[mediumvioletred::b]| |/ _/ __ \\______\n[mediumvioletred::b]| < \\____ / ___/\n[mediumvioletred::b]| | \\ / /\\___ \\ \n[mediumvioletred::b]|____|__ \\ /____//____ >\n[mediumvioletred::b] \\/ \\/ \n",
"[#c71585::b] ____ __.________ \n[#c71585::b]| |/ _/ __ \\______\n[#c71585::b]| < \\____ / ___/\n[#c71585::b]| | \\ / /\\___ \\ \n[#c71585::b]|____|__ \\ /____//____ >\n[#c71585::b] \\/ \\/ \n",
"blee",
"[white::b]blee\n",
},
"err": {
"[red::b] ____ __.________ \n[red::b]| |/ _/ __ \\______\n[red::b]| < \\____ / ___/\n[red::b]| | \\ / /\\___ \\ \n[red::b]|____|__ \\ /____//____ >\n[red::b] \\/ \\/ \n",
"[#ff0000::b] ____ __.________ \n[#ff0000::b]| |/ _/ __ \\______\n[#ff0000::b]| < \\____ / ___/\n[#ff0000::b]| | \\ / /\\___ \\ \n[#ff0000::b]|____|__ \\ /____//____ >\n[#ff0000::b] \\/ \\/ \n",
"blee",
"[white::b]blee\n",
},

View File

@ -17,9 +17,9 @@ func TestNewMenu(t *testing.T) {
{Mnemonic: "0", Description: "zero", Visible: true},
})
assert.Equal(t, " [fuchsia:-:b]<0> [white:-:d]zero ", v.GetCell(0, 0).Text)
assert.Equal(t, " [dodgerblue:-:b]<a> [white:-:d]bleeA ", v.GetCell(0, 1).Text)
assert.Equal(t, " [dodgerblue:-:b]<b> [white:-:d]bleeB ", v.GetCell(1, 1).Text)
assert.Equal(t, " [#ff00ff:-:b]<0> [#ffffff:-:d]zero ", v.GetCell(0, 0).Text)
assert.Equal(t, " [#1e90ff:-:b]<a> [#ffffff:-:d]bleeA ", v.GetCell(0, 1).Text)
assert.Equal(t, " [#1e90ff:-:b]<b> [#ffffff:-:d]bleeB ", v.GetCell(1, 1).Text)
}
func TestActionHints(t *testing.T) {

View File

@ -129,6 +129,7 @@ func (p *Prompt) keyboard(evt *tcell.EventKey) *tcell.EventKey {
return evt
}
// nolint:exhaustive
switch evt.Key() {
case tcell.KeyBackspace2, tcell.KeyBackspace, tcell.KeyDelete:
p.model.Delete()
@ -242,6 +243,7 @@ func (p *Prompt) iconFor(k model.BufferKind) rune {
return ' '
}
// nolint:exhaustive
switch k {
case model.CommandBuffer:
return '🐶'
@ -254,6 +256,7 @@ func (p *Prompt) iconFor(k model.BufferKind) rune {
// Helpers...
func colorFor(k model.BufferKind) tcell.Color {
// nolint:exhaustive
switch k {
case model.CommandBuffer:
return tcell.ColorAqua

View File

@ -114,8 +114,9 @@ func (s *SelectTable) selectionChanged(r, c int) {
if r < 0 {
return
}
cell := s.GetCell(r, c)
s.SetSelectedStyle(tcell.StyleDefault.Foreground(s.fgColor).Background(cell.Color).Attributes(tcell.AttrBold))
if cell := s.GetCell(r, c); cell != nil {
s.SetSelectedStyle(tcell.StyleDefault.Foreground(s.fgColor).Background(cell.Color).Attributes(tcell.AttrBold))
}
}
// ClearMarks delete all marked items.
@ -142,11 +143,9 @@ func (s *SelectTable) ToggleMark() {
s.marks[sel] = struct{}{}
}
cell := s.GetCell(s.GetSelectedRowIndex(), 0)
if cell == nil {
return
if cell := s.GetCell(s.GetSelectedRowIndex(), 0); cell != nil {
s.SetSelectedStyle(tcell.StyleDefault.Foreground(cell.BackgroundColor).Background(cell.Color).Attributes(tcell.AttrBold))
}
s.SetSelectedStyle(tcell.StyleDefault.Foreground(cell.BackgroundColor).Background(cell.Color).Attributes(tcell.AttrBold))
}
// SpanMark toggles marked row

View File

@ -622,7 +622,7 @@ func (a *App) aliasCmd(evt *tcell.EventKey) *tcell.EventKey {
func (a *App) gotoResource(cmd, path string, clearStack bool) error {
err := a.command.run(cmd, path, clearStack)
if err == nil {
return err
return nil
}
c := NewCow(a, err.Error())

View File

@ -62,9 +62,6 @@ func (c *ClusterInfo) hasMetrics() bool {
func (c *ClusterInfo) layout() {
for row, section := range []string{"Context", "Cluster", "User", "K9s Rev", "K8s Rev", "CPU", "MEM"} {
if (section == "CPU" || section == "MEM") && !c.hasMetrics() {
continue
}
c.SetCell(row, 0, c.sectionCell(section))
c.SetCell(row, 1, c.infoCell(render.NAValue))
}
@ -118,6 +115,9 @@ func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) {
row = c.setCell(row, ui.AsPercDelta(prev.Cpu, curr.Cpu))
_ = c.setCell(row, ui.AsPercDelta(prev.Mem, curr.Mem))
c.setDefCon(curr.Cpu, curr.Mem)
} else {
row = c.setCell(row, "[orangered::b]n/a")
_ = c.setCell(row, "[orangered::b]n/a")
}
c.updateStyle()
})
@ -158,6 +158,7 @@ func (c *ClusterInfo) updateStyle() {
// Helpers...
func flashLevel(l config.SeverityLevel) model.FlashLevel {
// nolint:exhaustive
switch l {
case config.SeverityHigh:
return model.FlashErr
@ -169,6 +170,7 @@ func flashLevel(l config.SeverityLevel) model.FlashLevel {
}
func flashMessage(l config.SeverityLevel) string {
// nolint:exhaustive
switch l {
case config.SeverityHigh:
return "Critical"

View File

@ -165,7 +165,7 @@ func (c *CronJob) makeSuspendForm(sel string, suspend bool) *tview.Form {
func (c *CronJob) toggleSuspend(ctx context.Context, path string) error {
res, err := dao.AccessorFor(c.App().factory, c.GVR())
if err != nil {
return nil
return err
}
cronJob, ok := res.(*dao.CronJob)
if !ok {

View File

@ -173,7 +173,7 @@ func clearScreen() {
const (
k9sShell = "k9s-shell"
k9sShellRetryCount = 10
k9sShellRetryDelay = 500 * time.Millisecond
k9sShellRetryDelay = 1 * time.Second
)
func ssh(a *App, node string) error {
@ -218,6 +218,7 @@ func nukeK9sShell(a *App) error {
}
func launchShellPod(a *App, node string) error {
a.Flash().Infof("Launching node shell on %s...", node)
ns := a.Config.K9s.ActiveCluster().ShellPod.Namespace
spec := k9sShellPod(node, a.Config.K9s.ActiveCluster().ShellPod)
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
@ -242,6 +243,7 @@ func launchShellPod(a *App, node string) error {
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod); err != nil {
return err
}
log.Debug().Msgf("Checking shell pod [%d] %v", i, pod.Status.Phase)
if pod.Status.Phase == v1.PodRunning {
return nil
}
@ -259,6 +261,30 @@ func k9sShellPod(node string, cfg *config.ShellPod) v1.Pod {
var grace int64
var priv bool = true
log.Debug().Msgf("Shell Config %#v", cfg)
c := v1.Container{
Name: k9sShell,
Image: cfg.Image,
VolumeMounts: []v1.VolumeMount{
{
Name: "root-vol",
MountPath: "/host",
ReadOnly: true,
},
},
Resources: asResource(cfg.Limits),
Stdin: true,
SecurityContext: &v1.SecurityContext{
Privileged: &priv,
},
}
if len(cfg.Command) != 0 {
c.Command = cfg.Command
}
if len(cfg.Args) > 0 {
c.Args = cfg.Args
}
return v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: k9sShellPodName(),
@ -280,24 +306,7 @@ func k9sShellPod(node string, cfg *config.ShellPod) v1.Pod {
},
},
},
Containers: []v1.Container{
{
Name: k9sShell,
Image: cfg.Image,
VolumeMounts: []v1.VolumeMount{
{
Name: "root-vol",
MountPath: "/host",
ReadOnly: true,
},
},
Resources: asResource(cfg.Limits),
Stdin: true,
SecurityContext: &v1.SecurityContext{
Privileged: &priv,
},
},
},
Containers: []v1.Container{c},
},
}
}

View File

@ -42,7 +42,7 @@ func NewHelp() *Help {
// Init initializes the component.
func (h *Help) Init(ctx context.Context) error {
if err := h.Table.Init(ctx); err != nil {
return nil
return err
}
h.SetSelectable(false, false)
h.resetTitle()

View File

@ -23,16 +23,16 @@ const liveViewTitleFmt = "[fg:bg:b] %s([hilite:bg:b]%s[fg:bg:-])[fg:bg:-] "
type LiveView struct {
*tview.Flex
title string
model model.ResourceViewer
text *tview.TextView
actions ui.KeyActions
app *App
title string
cmdBuff *model.FishBuff
model model.ResourceViewer
currentRegion, maxRegions int
cancel context.CancelFunc
fullScreen bool
managedField bool
cancel context.CancelFunc
autoRefresh bool
}
@ -196,7 +196,9 @@ func (v *LiveView) Start() {
}
return
}
v.model.Refresh(v.defaultCtx())
if err := v.model.Refresh(v.defaultCtx()); err != nil {
log.Error().Err(err).Msgf("refresh failed")
}
}
func (v *LiveView) defaultCtx() context.Context {
@ -241,6 +243,11 @@ func (v *LiveView) toggleFullScreenCmd(evt *tcell.EventKey) *tcell.EventKey {
v.fullScreen = !v.fullScreen
v.SetFullScreen(v.fullScreen)
v.Box.SetBorder(!v.fullScreen)
if v.fullScreen {
v.Box.SetBorderPadding(0, 0, 0, 0)
} else {
v.Box.SetBorderPadding(0, 0, 1, 1)
}
return nil
}

View File

@ -409,6 +409,11 @@ func (l *Log) toggleFullScreenCmd(evt *tcell.EventKey) *tcell.EventKey {
func (l *Log) goFullScreen() {
l.SetFullScreen(l.indicator.FullScreen())
l.Box.SetBorder(!l.indicator.FullScreen())
if l.indicator.FullScreen() {
l.logs.SetBorderPadding(0, 0, 0, 0)
} else {
l.logs.SetBorderPadding(0, 0, 1, 1)
}
}
// ----------------------------------------------------------------------------

View File

@ -63,7 +63,7 @@ func (p *PortForwardExtender) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey {
func (p *PortForwardExtender) fetchPodName(path string) (string, error) {
res, err := dao.AccessorFor(p.App().factory, p.GVR())
if err != nil {
return "", nil
return "", err
}
ctrl, ok := res.(dao.Controller)
if !ok {

View File

@ -64,7 +64,7 @@ func (r *RestartExtender) restartCmd(evt *tcell.EventKey) *tcell.EventKey {
func (r *RestartExtender) restartRollout(ctx context.Context, path string) error {
res, err := dao.AccessorFor(r.App().factory, r.GVR())
if err != nil {
return nil
return err
}
s, ok := res.(dao.Restartable)
if !ok {

View File

@ -113,7 +113,7 @@ func (s *ScaleExtender) makeStyledForm() *tview.Form {
func (s *ScaleExtender) scale(ctx context.Context, path string, replicas int) error {
res, err := dao.AccessorFor(s.App().factory, s.GVR())
if err != nil {
return nil
return err
}
scaler, ok := res.(dao.Scalable)
if !ok {

View File

@ -14,44 +14,44 @@ func TestYaml(t *testing.T) {
{
`api: fred
version: v1`,
`[steelblue::b]api[white::-]: [papayawhip::]fred
[steelblue::b]version[white::-]: [papayawhip::]v1`,
`[#4682b4::b]api[#ffffff::-]: [#ffefd5::]fred
[#4682b4::b]version[#ffffff::-]: [#ffefd5::]v1`,
},
{
`api: <<<"search_0">>>fred<<<"">>>
version: v1`,
`[steelblue::b]api[white::-]: [papayawhip::]["search_0"]fred[""]
[steelblue::b]version[white::-]: [papayawhip::]v1`,
`[#4682b4::b]api[#ffffff::-]: [#ffefd5::]["search_0"]fred[""]
[#4682b4::b]version[#ffffff::-]: [#ffefd5::]v1`,
},
{
`api:
version: v1`,
`[steelblue::b]api[white::-]:
[steelblue::b]version[white::-]: [papayawhip::]v1`,
`[#4682b4::b]api[#ffffff::-]:
[#4682b4::b]version[#ffffff::-]: [#ffefd5::]v1`,
},
{
" fred:blee",
"[papayawhip::] fred:blee",
"[#ffefd5::] fred:blee",
},
{
"fred blee: blee",
"[steelblue::b]fred blee[white::-]: [papayawhip::]blee",
"[#4682b4::b]fred blee[#ffffff::-]: [#ffefd5::]blee",
},
{
"Node-Selectors: <none>",
"[steelblue::b]Node-Selectors[white::-]: [papayawhip::] <none>",
"[#4682b4::b]Node-Selectors[#ffffff::-]: [#ffefd5::] <none>",
},
{
"fred.blee: <none>",
"[steelblue::b]fred.blee[white::-]: [papayawhip::] <none>",
"[#4682b4::b]fred.blee[#ffffff::-]: [#ffefd5::] <none>",
},
{
"certmanager.k8s.io/cluster-issuer: nameOfClusterIssuer",
"[steelblue::b]certmanager.k8s.io/cluster-issuer[white::-]: [papayawhip::]nameOfClusterIssuer",
"[#4682b4::b]certmanager.k8s.io/cluster-issuer[#ffffff::-]: [#ffefd5::]nameOfClusterIssuer",
},
{
"Message: Pod The node was low on resource: [DiskPressure].",
"[steelblue::b]Message[white::-]: [papayawhip::]Pod The node was low on resource: [DiskPressure[].",
"[#4682b4::b]Message[#ffffff::-]: [#ffefd5::]Pod The node was low on resource: [DiskPressure[].",
},
}

View File

@ -56,6 +56,7 @@ func (*Section) outcomeRefs(parent *TreeNode, section render.Section) {
func colorize(s string, l config.Level) string {
c := "green"
// nolint:exhaustive
switch l {
case config.ErrorLevel:
c = "red"