From 5c5fcba6d8252d876ac278df07fc34d87d9d4ad9 Mon Sep 17 00:00:00 2001 From: Fernand Galiana Date: Thu, 18 Sep 2025 09:33:35 -0600 Subject: [PATCH] Rel v0.50.11 (#3569) * fix #3567 #3566 * release notes --- Makefile | 2 +- change_logs/release_v0.50.11.md | 30 +++++++++++++++++++++++++++ internal/client/gvr.go | 2 +- internal/config/alias_test.go | 22 +++++++++++++++++--- internal/view/cmd/args.go | 8 ++++--- internal/view/cmd/interpreter.go | 2 -- internal/view/cmd/interpreter_test.go | 21 +++++++++++++++++++ internal/view/cmd/types.go | 4 ++-- internal/view/command.go | 2 +- internal/view/command_test.go | 6 +++--- snap/snapcraft.yaml | 2 +- 11 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 change_logs/release_v0.50.11.md diff --git a/Makefile b/Makefile index 322022de..65011237 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ NAME := k9s -VERSION ?= v0.50.10 +VERSION ?= v0.50.11 PACKAGE := github.com/derailed/$(NAME) OUTPUT_BIN ?= execs/${NAME} GO_FLAGS ?= diff --git a/change_logs/release_v0.50.11.md b/change_logs/release_v0.50.11.md new file mode 100644 index 00000000..a4e67790 --- /dev/null +++ b/change_logs/release_v0.50.11.md @@ -0,0 +1,30 @@ + + +# Release v0.50.11 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! +I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev +and see if we're happier with some of the fixes! +If you've filed an issue please help me verify and close. + +Your support, kindness and awesome suggestions to make K9s better are, as ever, very much noted and appreciated! +Also big thanks to all that have allocated their own time to help others on both slack and on this repo!! + +As you may know, K9s is not pimped out by corps with deep pockets, thus if you feel K9s is helping your Kubernetes journey, +please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/zt-3360a389v-ElLHrb0Dp1kAXqYUItSAFA) + +## Maintenance Release! + +Oh dear! Hopefully we're happier on this drop?? Apologizes for the `disturbance in the farce`... + +## Resolved Issues + +* [#3567](https://github.com/derailed/k9s/issues/3567) Extra slash '/' added when filtering from the command prompt +* [#3566](https://github.com/derailed/k9s/issues/3566) unable to switch context or use k9s after upgrade to 0.50.10 + +--- + © 2025 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)# \ No newline at end of file diff --git a/internal/client/gvr.go b/internal/client/gvr.go index c6d90bf6..9747494a 100644 --- a/internal/client/gvr.go +++ b/internal/client/gvr.go @@ -88,7 +88,7 @@ func (g *GVR) IsCommand() bool { } func (g *GVR) IsK8sRes() bool { - return g != nil && (strings.Contains(g.raw, "/") || reservedGVRs.Has(g)) + return g != nil && ((strings.Contains(g.raw, "/") && !strings.Contains(g.raw, " /")) || reservedGVRs.Has(g)) } // WithSubResource builds a new gvr with a sub resource. diff --git a/internal/config/alias_test.go b/internal/config/alias_test.go index c49ddb39..afdeddca 100644 --- a/internal/config/alias_test.go +++ b/internal/config/alias_test.go @@ -201,14 +201,14 @@ func TestAliasResolve(t *testing.T) { exp: "ppo", ok: true, gvr: client.PodGVR, - cmd: cmd.NewInterpreter("v1/pods a=b,b=c default"), + cmd: cmd.NewInterpreter("v1/pods 'a=b,b=c' default"), }, "full-alias": { exp: "ppc", ok: true, gvr: client.PodGVR, - cmd: cmd.NewInterpreter("v1/pods @fred app=fred default"), + cmd: cmd.NewInterpreter("v1/pods @fred 'app=fred' default"), }, "plain-filter": { @@ -229,7 +229,21 @@ func TestAliasResolve(t *testing.T) { exp: "ppc /fred @bozo ns-1", ok: true, gvr: client.PodGVR, - cmd: cmd.NewInterpreter("v1/pods @bozo /fred app=fred ns-1"), + cmd: cmd.NewInterpreter("v1/pods @bozo /fred 'app=fred' ns-1"), + }, + + "filtered": { + exp: "pc", + ok: true, + gvr: client.PodGVR, + cmd: cmd.NewInterpreter("v1/pods /cilium kube-system"), + }, + + "labels-in": { + exp: "ppp", + ok: true, + gvr: client.PodGVR, + cmd: cmd.NewInterpreter("v1/pods 'app in (be,fe)'"), }, } @@ -241,6 +255,8 @@ func TestAliasResolve(t *testing.T) { a.Define(client.NewGVR("pod default"), "pp") a.Define(client.NewGVR("pipo a=b,b=c default"), "ppo") a.Define(client.NewGVR("pod default app=fred @fred"), "ppc") + a.Define(client.NewGVR("pod /cilium kube-system"), "pc") + a.Define(client.NewGVR("pod 'app in (be,fe)'"), "ppp") for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { diff --git a/internal/view/cmd/args.go b/internal/view/cmd/args.go index 478eb50f..cd53ad83 100644 --- a/internal/view/cmd/args.go +++ b/internal/view/cmd/args.go @@ -48,12 +48,12 @@ func newArgs(p *Interpreter, aa []string) args { arguments[filterKey] = strings.ToLower(a[1:]) } - case isLabelArg(a): - arguments[labelKey] = strings.ToLower(a) - case strings.Index(a, contextFlag) == 0: arguments[contextKey] = a[1:] + case isLabelArg(a): + arguments[labelKey] = strings.ToLower(a) + default: switch { case p.IsContextCmd(): @@ -86,6 +86,8 @@ func (a args) String() string { for _, k := range slices.Sorted(kk) { v := a[k] switch k { + case labelKey: + v = "'" + v + "'" case filterKey: v = filterFlag + v case contextKey: diff --git a/internal/view/cmd/interpreter.go b/internal/view/cmd/interpreter.go index 51be96b6..d0951043 100644 --- a/internal/view/cmd/interpreter.go +++ b/internal/view/cmd/interpreter.go @@ -52,9 +52,7 @@ func (c *Interpreter) Merge(p *Interpreter) { } c.cmd = p.cmd for k, v := range p.args { - // if _, ok := c.args[k]; !ok { c.args[k] = v - // } } c.line = c.cmd + " " + c.args.String() } diff --git a/internal/view/cmd/interpreter_test.go b/internal/view/cmd/interpreter_test.go index 65b7e391..2cae281f 100644 --- a/internal/view/cmd/interpreter_test.go +++ b/internal/view/cmd/interpreter_test.go @@ -177,31 +177,42 @@ func TestFilterCmd(t *testing.T) { filter string }{ "empty": {}, + "normal": { cmd: "pod /fred", ok: true, filter: "fred", }, + "caps": { cmd: "POD /FRED", ok: true, filter: "fred", }, + "filter+ns": { cmd: "pod /fred ns1", ok: true, filter: "fred", }, + "ns+filter": { cmd: "pod ns1 /fred", ok: true, filter: "fred", }, + "ns+filter+labels": { cmd: "pod ns1 /fred app=blee,fred=zorg", ok: true, filter: "fred", }, + + "filtered": { + cmd: "pod /cilium kube-system", + ok: true, + filter: "cilium", + }, } for k := range uu { @@ -431,24 +442,34 @@ func TestContextCmd(t *testing.T) { ctx string }{ "empty": {}, + "happy-full": { cmd: "context ctx1", ok: true, ctx: "ctx1", }, + "happy-alias": { cmd: "ctx ctx1", ok: true, ctx: "ctx1", }, + "toast": { cmd: "ctxto ctx1", }, + "caps": { cmd: "ctx Dev", ok: true, ctx: "Dev", }, + + "contains-key": { + cmd: "ctx kind-fred", + ok: true, + ctx: "kind-fred", + }, } for k := range uu { diff --git a/internal/view/cmd/types.go b/internal/view/cmd/types.go index 052e2c92..0d2ea530 100644 --- a/internal/view/cmd/types.go +++ b/internal/view/cmd/types.go @@ -17,8 +17,8 @@ const ( labelFlagEq = "=" labelFlagEqs = "==" labelFlagNotEq = "!=" - labelFlagIn = "in" - labelFlagNotin = "notin" + labelFlagIn = " in " + labelFlagNotin = " notin " labelFlagQuote = "'" label fuzzyFlag = "-f" diff --git a/internal/view/command.go b/internal/view/command.go index 2cfbaaad..bfe44d9d 100644 --- a/internal/view/command.go +++ b/internal/view/command.go @@ -215,7 +215,7 @@ func (c *Command) run(p *cmd.Interpreter, fqn string, clearStack, pushCmd bool) co.SetFilter("", true) co.SetLabelSelector(labels.Everything(), true) if f, ok := p.FilterArg(); ok { - co.SetFilter("/"+f, true) + co.SetFilter(f, true) } if f, ok := p.FuzzyArg(); ok { co.SetFilter("-f "+f, true) diff --git a/internal/view/command_test.go b/internal/view/command_test.go index 5795cc67..b497859d 100644 --- a/internal/view/command_test.go +++ b/internal/view/command_test.go @@ -47,14 +47,14 @@ func Test_viewMetaFor(t *testing.T) { "custom-alias": { cmd: "pdl", gvr: client.PodGVR, - p: cmd.NewInterpreter("v1/pods @fred app=blee default"), + p: cmd.NewInterpreter("v1/pods @fred 'app=blee' default"), err: errors.New("blee"), }, "inception": { cmd: "pdal blee", gvr: client.PodGVR, - p: cmd.NewInterpreter("v1/pods @fred app=blee blee"), + p: cmd.NewInterpreter("v1/pods @fred 'app=blee' blee"), err: errors.New("blee"), }, } @@ -66,7 +66,7 @@ func Test_viewMetaFor(t *testing.T) { } c.alias.Define(client.PodGVR, "po", "pod", "pods", client.PodGVR.String()) c.alias.Define(client.NewGVR("pod default"), "pd") - c.alias.Define(client.NewGVR("pod @fred app=blee default"), "pdl") + c.alias.Define(client.NewGVR("pod @fred 'app=blee' default"), "pdl") c.alias.Define(client.NewGVR("pdl"), "pdal") for k, u := range uu { diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index b62e1cab..96dc0f9c 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: k9s base: core22 -version: 'v0.50.10' +version: 'v0.50.11' summary: K9s is a CLI to view and manage your Kubernetes clusters. description: | K9s is a CLI to view and manage your Kubernetes clusters. By leveraging a terminal UI, you can easily traverse Kubernetes resources and view the state of your clusters in a single powerful session.