Skip to content

Commit

Permalink
Merge branch 'master' into fix/cluster_config_favorite_ns_limit
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed authored Jan 19, 2025
2 parents 0c1436a + d72467a commit f176d76
Show file tree
Hide file tree
Showing 17 changed files with 58 additions and 44 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1088,12 +1088,12 @@ to make this project a reality!
## Meet The Core Team!
If you have chops in GO and K8s and would like to offer your time to help maintain and enhance this project, please reach out to me.
* [Fernand Galiana](https://github.com/derailed)
* <img src="assets/mail.png" width="16" height="auto" alt="email"/> [email protected]
* <img src="assets/twitter.png" width="16" height="auto" alt="twitter"/> [@kitesurfer](https://twitter.com/kitesurfer?lang=en)
* [Aleksei Romanenko](https://github.com/slimus)
We always enjoy hearing from folks who benefit from our work!
## Contributions Guideline
Expand Down
5 changes: 1 addition & 4 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,16 +545,13 @@ func (a *APIClient) SwitchContext(name string) error {
if err := a.config.SwitchContext(name); err != nil {
return err
}
if err := a.invalidateCache(); err != nil {
return err
}
a.reset()
ResetMetrics()

// Need reload to pick up any kubeconfig changes.
a.config = NewConfig(a.config.flags)

return nil
return a.invalidateCache()
}

func (a *APIClient) reset() {
Expand Down
2 changes: 1 addition & 1 deletion internal/config/data/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestHelperInList(t *testing.T) {

func TestEnsureDirPathNone(t *testing.T) {
var mod os.FileMode = 0744
dir := filepath.Join("/tmp", "fred")
dir := filepath.Join("/tmp", "k9s-test")
os.Remove(dir)

path := filepath.Join(dir, "duh.yaml")
Expand Down
3 changes: 3 additions & 0 deletions internal/config/data/proxy.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s

package data

// Proxy tracks a context's proxy configuration.
Expand Down
8 changes: 2 additions & 6 deletions internal/config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
v1 "k8s.io/api/core/v1"
)

func isBoolSet(b *bool) bool {
// IsBoolSet checks if a bool ptr is set.
func IsBoolSet(b *bool) bool {
return b != nil && *b
}

Expand Down Expand Up @@ -70,8 +71,3 @@ func MustK9sUser() string {
}
return usr.Username
}

// IsBoolSet checks if a bool prt is set.
func IsBoolSet(b *bool) bool {
return b != nil && *b
}
6 changes: 3 additions & 3 deletions internal/config/k9s.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (k *K9s) Override(k9sFlags *Flags) {

// IsHeadless returns headless setting.
func (k *K9s) IsHeadless() bool {
if isBoolSet(k.manualHeadless) {
if IsBoolSet(k.manualHeadless) {
return true
}

Expand All @@ -301,7 +301,7 @@ func (k *K9s) IsHeadless() bool {

// IsLogoless returns logoless setting.
func (k *K9s) IsLogoless() bool {
if isBoolSet(k.manualLogoless) {
if IsBoolSet(k.manualLogoless) {
return true
}

Expand All @@ -310,7 +310,7 @@ func (k *K9s) IsLogoless() bool {

// IsCrumbsless returns crumbsless setting.
func (k *K9s) IsCrumbsless() bool {
if isBoolSet(k.manualCrumbsless) {
if IsBoolSet(k.manualCrumbsless) {
return true
}

Expand Down
2 changes: 1 addition & 1 deletion internal/dao/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func getContainerStatus(kind string, name string, status v1.PodStatus) *v1.Conta
func (c *Container) fetchPod(fqn string) (*v1.Pod, error) {
o, err := c.getFactory().Get("v1/pods", fqn, true, labels.Everything())
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to locate pod %q: %w", fqn, err)
}
var po v1.Pod
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &po)
Expand Down
8 changes: 3 additions & 5 deletions internal/dao/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,12 @@ func (g *Generic) List(ctx context.Context, ns string) ([]runtime.Object, error)
ns = client.BlankNamespace
}

var (
ll *unstructured.UnstructuredList
err error
)
dial, err := g.dynClient()
if err != nil {
return nil, err
}

var ll *unstructured.UnstructuredList
if client.IsClusterScoped(ns) {
ll, err = dial.List(ctx, metav1.ListOptions{LabelSelector: labelSel})
} else {
Expand All @@ -71,12 +68,13 @@ func (g *Generic) List(ctx context.Context, ns string) ([]runtime.Object, error)

// Get returns a given resource.
func (g *Generic) Get(ctx context.Context, path string) (runtime.Object, error) {
var opts metav1.GetOptions
ns, n := client.Namespaced(path)
dial, err := g.dynClient()
if err != nil {
return nil, err
}

var opts metav1.GetOptions
if client.IsClusterScoped(ns) {
return dial.Get(ctx, n, opts)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/dao/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func FetchNode(ctx context.Context, f Factory, path string) (*v1.Node, error) {
return nil, fmt.Errorf("user is not authorized to list nodes")
}

o, err := f.Get("v1/nodes", client.FQN(client.ClusterScope, path), false, labels.Everything())
o, err := f.Get("v1/nodes", client.FQN(client.ClusterScope, path), true, labels.Everything())
if err != nil {
return nil, err
}
Expand Down
8 changes: 2 additions & 6 deletions internal/dao/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ func loadCRDs(f Factory, m ResourceMetas) {
var meta metav1.APIResource
meta.Kind = crd.Spec.Names.Kind
meta.Group = crd.Spec.Group
meta.Name = crd.Name
meta.Name = strings.TrimSuffix(crd.Name, "."+meta.Group)

meta.SingularName = crd.Spec.Names.Singular
meta.ShortNames = crd.Spec.Names.ShortNames
meta.Namespaced = crd.Spec.Scope == apiext.NamespaceScoped
Expand All @@ -435,11 +436,6 @@ func loadCRDs(f Factory, m ResourceMetas) {
}
}

// meta, errs := extractMeta(o)
// if len(errs) > 0 {
// log.Error().Err(errs[0]).Msgf("Fail to extract CRD meta (%d) errors", len(errs))
// continue
// }
meta.Categories = append(meta.Categories, crdCat)
gvr := client.NewGVRFromMeta(meta)
m[gvr] = meta
Expand Down
5 changes: 3 additions & 2 deletions internal/render/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ func (p Pod) Render(o interface{}, ns string, row *model1.Row) error {
}
c, r := gatherCoMX(&po.Spec, ccmx)
phase := p.Phase(&po)
row.ID = client.MetaFQN(po.ObjectMeta)

row.ID = client.MetaFQN(po.ObjectMeta)
row.Fields = model1.Fields{
po.Namespace,
po.Name,
Expand Down Expand Up @@ -254,7 +254,7 @@ func cosLimits(cc []v1.Container) (resource.Quantity, resource.Quantity) {
for _, c := range cc {
limits := c.Resources.Limits
if len(limits) == 0 {
return resource.Quantity{}, resource.Quantity{}
continue
}
if limits.Cpu() != nil {
cpu.Add(*limits.Cpu())
Expand All @@ -263,6 +263,7 @@ func cosLimits(cc []v1.Container) (resource.Quantity, resource.Quantity) {
mem.Add(*limits.Memory())
}
}

return *cpu, *mem
}

Expand Down
16 changes: 15 additions & 1 deletion internal/render/rs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package render
import (
"fmt"
"strconv"
"strings"

"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/model1"
Expand Down Expand Up @@ -34,7 +35,9 @@ func (ReplicaSet) Header(ns string) model1.Header {
model1.HeaderColumn{Name: "DESIRED", Align: tview.AlignRight},
model1.HeaderColumn{Name: "CURRENT", Align: tview.AlignRight},
model1.HeaderColumn{Name: "READY", Align: tview.AlignRight},
model1.HeaderColumn{Name: "LABELS", Wide: true},
model1.HeaderColumn{Name: "CONTAINERS", Wide: true},
model1.HeaderColumn{Name: "IMAGES", Wide: true},
model1.HeaderColumn{Name: "SELECTOR", Wide: true},
model1.HeaderColumn{Name: "VALID", Wide: true},
model1.HeaderColumn{Name: "AGE", Time: true},
}
Expand All @@ -46,12 +49,21 @@ func (r ReplicaSet) Render(o interface{}, ns string, row *model1.Row) error {
if !ok {
return fmt.Errorf("expected ReplicaSet, but got %T", o)
}

var rs appsv1.ReplicaSet
err := runtime.DefaultUnstructuredConverter.FromUnstructured(raw.Object, &rs)
if err != nil {
return err
}

var (
cc = rs.Spec.Template.Spec.Containers
cos, imgs = make([]string, 0, len(cc)), make([]string, 0, len(cc))
)
for _, co := range cc {
cos, imgs = append(cos, co.Name), append(imgs, co.Image)
}

row.ID = client.MetaFQN(rs.ObjectMeta)
row.Fields = model1.Fields{
rs.Namespace,
Expand All @@ -60,6 +72,8 @@ func (r ReplicaSet) Render(o interface{}, ns string, row *model1.Row) error {
strconv.Itoa(int(*rs.Spec.Replicas)),
strconv.Itoa(int(rs.Status.Replicas)),
strconv.Itoa(int(rs.Status.ReadyReplicas)),
strings.Join(cos, ","),
strings.Join(imgs, ","),
mapToStr(rs.Labels),
AsStatus(r.diagnose(rs)),
ToAge(rs.GetCreationTimestamp()),
Expand Down
2 changes: 1 addition & 1 deletion internal/view/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ func (a *App) Run() error {
})
}()

if err := a.command.defaultCmd(); err != nil {
if err := a.command.defaultCmd(true); err != nil {
return err
}
a.SetRunning(true)
Expand Down
13 changes: 9 additions & 4 deletions internal/view/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,19 +209,24 @@ func (c *Command) run(p *cmd.Interpreter, fqn string, clearStack bool) error {
return c.exec(p, gvr, co, clearStack)
}

func (c *Command) defaultCmd() error {
func (c *Command) defaultCmd(isRoot bool) error {
if c.app.Conn() == nil || !c.app.Conn().ConnectionOK() {
return c.run(cmd.NewInterpreter("context"), "", true)
}

defCmd := "pod"
if isRoot {
defCmd = "ctx"
}
p := cmd.NewInterpreter(c.app.Config.ActiveView())
if p.IsBlank() {
return c.run(p.Reset("pod"), "", true)
return c.run(p.Reset(defCmd), "", true)
}

if err := c.run(p, "", true); err != nil {
log.Error().Err(err).Msgf("Default run command failed %q", p.GetLine())
return c.run(p.Reset("pod"), "", true)
p = p.Reset(defCmd)
log.Error().Err(fmt.Errorf("Command failed. Using default command: %s", p.GetLine()))
return c.run(p, "", true)
}

return nil
Expand Down
3 changes: 2 additions & 1 deletion internal/view/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ func (l *Log) toggleAllContainers(evt *tcell.EventKey) *tcell.EventKey {

func (l *Log) filterCmd(evt *tcell.EventKey) *tcell.EventKey {
if !l.logs.cmdBuff.IsActive() {
fmt.Fprintln(l.ansiWriter)
return evt
}

Expand Down Expand Up @@ -451,7 +452,7 @@ func (l *Log) clearCmd(*tcell.EventKey) *tcell.EventKey {

func (l *Log) markCmd(*tcell.EventKey) *tcell.EventKey {
_, _, w, _ := l.GetRect()
fmt.Fprintf(l.ansiWriter, "\n[%s:-:b]%s[-:-:-]", l.app.Styles.Views().Log.FgColor.String(), strings.Repeat("", w-4))
fmt.Fprintf(l.ansiWriter, "\n[%s:-:b]%s[-:-:-]", l.app.Styles.Views().Log.FgColor.String(), strings.Repeat("-", w-4))
l.follow = true

return nil
Expand Down
2 changes: 0 additions & 2 deletions internal/view/pf.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"github.com/rs/zerolog/log"
)

const promptPage = "prompt"

// PortForward presents active portforward viewer.
type PortForward struct {
ResourceViewer
Expand Down
13 changes: 9 additions & 4 deletions internal/watch/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (

const (
defaultResync = 10 * time.Minute
defaultWaitTime = 250 * time.Millisecond
defaultWaitTime = 500 * time.Millisecond
)

// Factory tracks various resource informers.
Expand Down Expand Up @@ -72,13 +72,13 @@ func (f *Factory) Terminate() {

// List returns a resource collection.
func (f *Factory) List(gvr, ns string, wait bool, labels labels.Selector) ([]runtime.Object, error) {
if client.IsAllNamespace(ns) {
ns = client.BlankNamespace
}
inf, err := f.CanForResource(ns, gvr, client.ListAccess)
if err != nil {
return nil, err
}
if client.IsAllNamespace(ns) {
ns = client.BlankNamespace
}

var oo []runtime.Object
if client.IsClusterScoped(ns) {
Expand Down Expand Up @@ -110,6 +110,10 @@ func (f *Factory) HasSynced(gvr, ns string) (bool, error) {
// Get retrieves a given resource.
func (f *Factory) Get(gvr, fqn string, wait bool, sel labels.Selector) (runtime.Object, error) {
ns, n := namespaced(fqn)
if client.IsAllNamespace(ns) {
ns = client.BlankNamespace
}

inf, err := f.CanForResource(ns, gvr, []string{client.GetVerb})
if err != nil {
return nil, err
Expand All @@ -128,6 +132,7 @@ func (f *Factory) Get(gvr, fqn string, wait bool, sel labels.Selector) (runtime.
if client.IsClusterScoped(ns) {
return inf.Lister().Get(n)
}

return inf.Lister().ByNamespace(ns).Get(n)
}

Expand Down

0 comments on commit f176d76

Please sign in to comment.