From 4833de10c15a45fc4c37d9a3007b7ae846bd897c Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 4 Jan 2024 16:51:30 -0700 Subject: [PATCH] [Bug] Fix #2428 --- internal/config/config.go | 5 +++++ internal/config/data/config.go | 8 +++++++- internal/config/data/context.go | 15 +++++++++++++-- internal/config/k9s.go | 29 ++++++++++++++--------------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index c4b781b27d..32973dbaf0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -153,6 +153,7 @@ func (c *Config) FavNamespaces() []string { if err != nil { return nil } + ct.Validate(c.conn, c.settings) return ct.Namespace.Favorites } @@ -248,11 +249,15 @@ func (c *Config) SaveFile(path string) error { log.Error().Msgf("[Config] Unable to save K9s config file: %v", err) return err } + return os.WriteFile(path, cfg, 0644) } // Validate the configuration. func (c *Config) Validate() { + if c.K9s == nil { + c.K9s = NewK9s(c.conn, c.settings) + } c.K9s.Validate(c.conn, c.settings) } diff --git a/internal/config/data/config.go b/internal/config/data/config.go index 3faf5fcc27..234adc31d9 100644 --- a/internal/config/data/config.go +++ b/internal/config/data/config.go @@ -18,27 +18,33 @@ type Config struct { Context *Context `yaml:"k9s"` } +// NewConfig returns a new config. func NewConfig(ct *api.Context) *Config { return &Config{ Context: NewContextFromConfig(ct), } } +// Validate ensures config is in norms. func (c *Config) Validate(conn client.Connection, ks KubeSettings) { + if c.Context == nil { + c.Context = NewContext() + } c.Context.Validate(conn, ks) } +// Dump used for debugging. func (c *Config) Dump(w io.Writer) { bb, _ := yaml.Marshal(&c) fmt.Fprintf(w, "%s\n", string(bb)) } +// Save saves the config to disk. func (c *Config) Save(path string) error { if err := EnsureDirPath(path, DefaultDirMod); err != nil { return err } - cfg, err := yaml.Marshal(c) if err != nil { return err diff --git a/internal/config/data/context.go b/internal/config/data/context.go index 8f38676e54..90385f8a8c 100644 --- a/internal/config/data/context.go +++ b/internal/config/data/context.go @@ -32,6 +32,7 @@ func NewContext() *Context { } } +// NewContextFromConfig returns a config based on a kubecontext. func NewContextFromConfig(cfg *api.Context) *Context { return &Context{ Namespace: NewActiveNamespace(cfg.Namespace), @@ -42,12 +43,22 @@ func NewContextFromConfig(cfg *api.Context) *Context { } } -// Validate a context config. +// NewContextFromKubeConfig returns a new instance based on kubesettings or an error. +func NewContextFromKubeConfig(ks KubeSettings) (*Context, error) { + ct, err := ks.CurrentContext() + if err != nil { + return nil, err + } + + return NewContextFromConfig(ct), nil +} + +// Validate ensures a context config is tip top. func (c *Context) Validate(conn client.Connection, ks KubeSettings) { if c.PortForwardAddress == "" { c.PortForwardAddress = DefaultPFAddress } - if cl, err := ks.CurrentClusterName(); err != nil { + if cl, err := ks.CurrentClusterName(); err == nil { c.ClusterName = cl } diff --git a/internal/config/k9s.go b/internal/config/k9s.go index 69e4ddd5a0..1a536c7b5c 100644 --- a/internal/config/k9s.go +++ b/internal/config/k9s.go @@ -4,7 +4,7 @@ package config import ( - "errors" + "fmt" "path/filepath" "github.com/derailed/k9s/internal/client" @@ -148,11 +148,12 @@ func (k *K9s) ActiveContextDir() string { // ActiveContextNamespace fetch the context active ns. func (k *K9s) ActiveContextNamespace() (string, error) { - if k.activeConfig != nil { - return k.activeConfig.Context.Namespace.Active, nil + ct, err := k.ActiveContext() + if err != nil { + return "", err } - return "", errors.New("context config is not set") + return ct.Namespace.Active, nil } // ActiveContextName returns the active context name. @@ -162,14 +163,7 @@ func (k *K9s) ActiveContextName() string { // ActiveContext returns the currently active context. func (k *K9s) ActiveContext() (*data.Context, error) { - if k.activeConfig != nil { - if k.activeConfig.Context == nil { - ct, err := k.ks.CurrentContext() - if err != nil { - return nil, err - } - k.activeConfig.Context = data.NewContextFromConfig(ct) - } + if k.activeConfig != nil && k.activeConfig.Context != nil { return k.activeConfig.Context, nil } @@ -181,7 +175,7 @@ func (k *K9s) ActiveContext() (*data.Context, error) { return ct, nil } -// ActivateContext initializes the active context is not present. +// ActivateContext initializes the active context if not present. func (k *K9s) ActivateContext(n string) (*data.Context, error) { k.activeContextName = n ct, err := k.ks.GetContext(n) @@ -192,15 +186,19 @@ func (k *K9s) ActivateContext(n string) (*data.Context, error) { if err != nil { return nil, err } - // If the context specifies a default namespace, use it! + + k.Validate(k.conn, k.ks) if k.conn != nil { - k.Validate(k.conn, k.ks) + // If the context specifies a default namespace, use it! if ns := k.conn.ActiveNamespace(); ns != client.BlankNamespace { k.activeConfig.Context.Namespace.Active = ns } else { k.activeConfig.Context.Namespace.Active = client.DefaultNamespace } } + if k.activeConfig.Context == nil { + return nil, fmt.Errorf("context activation failed for: %s", n) + } return k.activeConfig.Context, nil } @@ -216,6 +214,7 @@ func (k *K9s) Reload() error { if err != nil { return err } + k.activeConfig.Validate(k.conn, k.ks) return nil }