Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed committed May 2, 2021
1 parent 627c38c commit a951b55
Show file tree
Hide file tree
Showing 13 changed files with 368 additions and 45 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,13 @@ k9s:
info:
fgColor: lightskyblue
sectionColor: steelblue
# Help panel styles
help:
fgColor: white
bgColor: black
keyColor: cyan
numKeyColor: blue
sectionColor: gray
frame:
# Borders styles.
border:
Expand Down
14 changes: 5 additions & 9 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,7 @@ func loadConfiguration() *config.Config {
k9sCfg.K9s.OverrideWrite(*k9sFlags.Write)
k9sCfg.K9s.OverrideCommand(*k9sFlags.Command)

if isBoolSet(k9sFlags.AllNamespaces) && k9sCfg.SetActiveNamespace(client.AllNamespaces) != nil {
log.Error().Msg("Setting active namespace")
}

if err := k9sCfg.Refine(k8sFlags); err != nil {
if err := k9sCfg.Refine(k8sFlags, k9sFlags); err != nil {
log.Error().Err(err).Msgf("refine failed")
}
conn, err := client.InitConnection(k8sCfg)
Expand All @@ -122,10 +118,6 @@ func loadConfiguration() *config.Config {
return k9sCfg
}

func isBoolSet(b *bool) bool {
return b != nil && *b
}

func parseLevel(level string) zerolog.Level {
switch level {
case "debug":
Expand Down Expand Up @@ -301,3 +293,7 @@ func initCertFlags() {
"Bearer token for authentication to the API server",
)
}

func isBoolSet(b *bool) bool {
return b != nil && *b
}
240 changes: 240 additions & 0 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions internal/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Config struct {
rawConfig *clientcmdapi.Config
restConfig *restclient.Config
mutex *sync.RWMutex
OverrideNS bool
}

// NewConfig returns a new k8s config or an error if the flags are invalid.
Expand Down
33 changes: 19 additions & 14 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ type (

// Config tracks K9s configuration options.
Config struct {
K9s *K9s `yaml:"k9s"`
client client.Connection
settings KubeSettings
K9s *K9s `yaml:"k9s"`
client client.Connection
settings KubeSettings
overrideNS bool
}
)

Expand All @@ -70,7 +71,7 @@ func NewConfig(ks KubeSettings) *Config {
}

// Refine the configuration based on cli args.
func (c *Config) Refine(flags *genericclioptions.ConfigFlags) error {
func (c *Config) Refine(flags *genericclioptions.ConfigFlags, k9sFlags *Flags) error {
cfg, err := flags.ToRawKubeConfigLoader().RawConfig()
if err != nil {
return err
Expand All @@ -90,22 +91,25 @@ func (c *Config) Refine(flags *genericclioptions.ConfigFlags) error {
return fmt.Errorf("The specified context %q does not exists in kubeconfig", c.K9s.CurrentContext)
}
c.K9s.CurrentCluster = context.Cluster
if len(context.Namespace) != 0 {
if err := c.SetActiveNamespace(context.Namespace); err != nil {
return err
}

var ns string
var override bool
if IsBoolSet(k9sFlags.AllNamespaces) {
ns, override = client.NamespaceAll, true
} else if isSet(flags.Namespace) {
ns, override = *flags.Namespace, true
} else if len(context.Namespace) != 0 {
ns = context.Namespace
}
if err := c.SetActiveNamespace(ns); err != nil {
return err
}
flags.Namespace, c.overrideNS = &ns, override

if isSet(flags.ClusterName) {
c.K9s.CurrentCluster = *flags.ClusterName
}

if isSet(flags.Namespace) {
if err := c.SetActiveNamespace(*flags.Namespace); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -193,6 +197,7 @@ func (c *Config) GetConnection() client.Connection {
// SetConnection set an api server connection.
func (c *Config) SetConnection(conn client.Connection) {
c.client = conn
c.client.Config().OverrideNS = c.overrideNS
}

// Load K9s configuration from file
Expand Down
4 changes: 4 additions & 0 deletions internal/config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ func EnsureFullPath(path string, mod os.FileMode) {
}
}
}

func IsBoolSet(b *bool) bool {
return b != nil && *b
}
21 changes: 21 additions & 0 deletions internal/config/styles.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,22 @@ type (
// Style tracks K9s styles.
Style struct {
Body Body `yaml:"body"`
Help Help `yaml:"help"`
Frame Frame `yaml:"frame"`
Info Info `yaml:"info"`
Views Views `yaml:"views"`
Dialog Dialog `yaml:"dialog"`
}

// Helps tracks help styles.
Help struct {
FgColor Color `yaml:"fgColor"`
BgColor Color `yaml:"bgColor"`
SectionColor Color `yaml:"sectionColor"`
KeyColor Color `yaml:"keyColor"`
NumKeyColor Color `yaml:"numKeyColor"`
}

// Body tracks body styles.
Body struct {
FgColor Color `yaml:"fgColor"`
Expand Down Expand Up @@ -236,6 +246,7 @@ func (c Colors) Colors() []tcell.Color {
func newStyle() Style {
return Style{
Body: newBody(),
Help: newHelp(),
Frame: newFrame(),
Info: newInfo(),
Views: newViews(),
Expand Down Expand Up @@ -290,6 +301,16 @@ func newFrame() Frame {
}
}

func newHelp() Help {
return Help{
FgColor: "cadetblue",
BgColor: "black",
SectionColor: "green",
KeyColor: "dodgerblue",
NumKeyColor: "fuchsia",
}
}

func newBody() Body {
return Body{
FgColor: "cadetblue",
Expand Down
2 changes: 1 addition & 1 deletion internal/view/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ func (a *App) helpCmd(evt *tcell.EventKey) *tcell.EventKey {
return nil
}

if err := a.inject(NewHelp()); err != nil {
if err := a.inject(NewHelp(a, a.Styles)); err != nil {
a.Flash().Err(err)
}

Expand Down
8 changes: 5 additions & 3 deletions internal/view/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,11 @@ func (c *Command) defaultCmd() error {
}
tokens := strings.Split(view, " ")
cmd := view
ns, err := c.app.Conn().Config().CurrentNamespaceName()
if err == nil && !isContextCmd(tokens[0]) {
cmd = tokens[0] + " " + ns
if len(tokens) == 1 || c.app.Conn().Config().OverrideNS {
ns, err := c.app.Conn().Config().CurrentNamespaceName()
if err == nil && !isContextCmd(tokens[0]) {
cmd = tokens[0] + " " + ns
}
}

if err := c.run(cmd, "", true); err != nil {
Expand Down
31 changes: 29 additions & 2 deletions internal/view/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/config"
"github.com/fatih/color"
"github.com/rs/zerolog/log"
v1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -192,11 +193,37 @@ func ssh(a *App, node string) error {
return err
}
ns := a.Config.K9s.ActiveCluster().ShellPod.Namespace
shellIn(a, client.FQN(ns, k9sShellPodName()), k9sShell)
sshIn(a, client.FQN(ns, k9sShellPodName()), k9sShell)

return nil
}

func sshIn(a *App, fqn, co string) {
cfg := a.Config.K9s.ActiveCluster().ShellPod
os, err := getPodOS(a.factory, fqn)
if err != nil {
log.Warn().Err(err).Msgf("os detect failed")
}

args := buildShellArgs("exec", fqn, co, a.Conn().Config().Flags().KubeConfig)
args = append(args, "--")
if len(cfg.Command) > 0 {
args = append(args, cfg.Command...)
args = append(args, cfg.Args...)
} else {
if os == windowsOS {
args = append(args, "--", powerShell)
}
args = append(args, "sh", "-c", shellCheck)
}
log.Debug().Msgf("ARGS %#v", args)

c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold)
if !runK(a, shellOpts{clear: true, banner: c.Sprintf(bannerFmt, fqn, co), args: args}) {
a.Flash().Err(errors.New("Shell exec failed"))
}
}

func nukeK9sShell(a *App) error {
cl := a.Config.K9s.CurrentCluster
if !a.Config.K9s.Clusters[cl].FeatureGates.NodeShell {
Expand Down Expand Up @@ -224,7 +251,7 @@ 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)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

dial, err := a.Conn().Dial()
Expand Down
44 changes: 29 additions & 15 deletions internal/view/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,28 @@ type HelpFunc func() model.MenuHints
type Help struct {
*Table

styles *config.Styles
hints HelpFunc
maxKey, maxDesc, maxRows int
}

// NewHelp returns a new help viewer.
func NewHelp() *Help {
return &Help{
Table: NewTable(client.NewGVR("help")),
func NewHelp(app *App, styles *config.Styles) *Help {
h := &Help{
Table: NewTable(client.NewGVR("help")),
styles: styles,
hints: app.Content.Top().Hints,
}
styles.AddListener(h)

return h
}

// StylesChanged notifies skin changed.
func (h *Help) StylesChanged(s *config.Styles) {
h.styles = s
h.SetBackgroundColor(s.BgColor())
h.build()
}

// Init initializes the component.
Expand Down Expand Up @@ -90,14 +104,14 @@ func (h *Help) build() {
h.Clear()

sections := []string{"RESOURCE", "GENERAL", "NAVIGATION", "HELP"}

h.maxRows = len(h.showGeneral())
ff := []HelpFunc{
h.app.Content.Top().Hints,
h.hints,
h.showGeneral,
h.showNav,
h.showHelp,
}

var col int
extras := h.app.Content.Top().ExtraHints()
for i, section := range sections {
Expand Down Expand Up @@ -281,15 +295,15 @@ func (h *Help) addSection(c int, title string, hh model.MenuHints) {
h.maxRows = len(hh)
}
row := 0
h.SetCell(row, c, titleCell(title))
h.SetCell(row, c, h.titleCell(title))
h.addSpacer(c + 1)
row++

for _, hint := range hh {
col := c
h.SetCell(row, col, keyCell(hint.Mnemonic, h.maxKey))
h.SetCell(row, col, h.keyCell(hint.Mnemonic, h.maxKey))
col++
h.SetCell(row, col, infoCell(hint.Description, h.maxDesc))
h.SetCell(row, col, h.infoCell(hint.Description, h.maxDesc))
row++
}

Expand Down Expand Up @@ -329,31 +343,31 @@ func keyConv(s string) string {
return strings.Replace(s, "alt", "opt", 1)
}

func titleCell(title string) *tview.TableCell {
func (h *Help) titleCell(title string) *tview.TableCell {
c := tview.NewTableCell(title)
c.SetTextColor(tcell.ColorGreen)
c.SetTextColor(h.Styles().K9s.Help.SectionColor.Color())
c.SetAttributes(tcell.AttrBold)
c.SetExpansion(1)
c.SetAlign(tview.AlignLeft)

return c
}

func keyCell(k string, width int) *tview.TableCell {
func (h *Help) keyCell(k string, width int) *tview.TableCell {
c := padCell(toMnemonic(k), width)
if _, err := strconv.Atoi(k); err != nil {
c.SetTextColor(tcell.ColorDodgerBlue)
c.SetTextColor(h.styles.K9s.Help.KeyColor.Color())
} else {
c.SetTextColor(tcell.ColorFuchsia)
c.SetTextColor(h.styles.K9s.Help.NumKeyColor.Color())
}
c.SetAttributes(tcell.AttrBold)

return c
}

func infoCell(info string, width int) *tview.TableCell {
func (h *Help) infoCell(info string, width int) *tview.TableCell {
c := padCell(info, width)
c.SetTextColor(tcell.ColorWhite)
c.SetTextColor(h.styles.K9s.Help.FgColor.Color())

return c
}
Expand Down
2 changes: 1 addition & 1 deletion internal/view/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestHelp(t *testing.T) {
po.Init(ctx)
app.Content.Push(po)

v := view.NewHelp()
v := view.NewHelp(app.Styles)

assert.Nil(t, v.Init(ctx))
assert.Equal(t, 25, v.GetRowCount())
Expand Down
6 changes: 6 additions & 0 deletions skins/gruvbox-light.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ k9s:
info:
fgColor: *magenta
sectionColor: *foreground
help:
fgColor: *foreground
bgColor: *background
keyColor: *magenta
numKeyColor: *blue
sectionColor: *green
dialog:
fgColor: *foreground
bgColor: *background
Expand Down

0 comments on commit a951b55

Please sign in to comment.