Skip to content

Commit

Permalink
release v0.25.16 (derailed#1400)
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed authored Dec 25, 2021
1 parent df613ec commit fc8ffe5
Show file tree
Hide file tree
Showing 20 changed files with 174 additions and 82 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ PACKAGE := github.com/derailed/$(NAME)
GIT_REV ?= $(shell git rev-parse --short HEAD)
SOURCE_DATE_EPOCH ?= $(shell date +%s)
DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ")
VERSION ?= v0.25.15
VERSION ?= v0.25.16
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

Expand Down
Binary file added assets/k9s-xmas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions change_logs/release_v0.25.16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>

# Release v0.25.16

## 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!

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/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)

### A Word From Our Sponsors...

I want to recognize the following folks that have been kind enough to join our sponsorship program and opted to `pay it forward`!

* [Sebastian Racs](https://github.com/sebracs)
* [Timothy C. Arland](https://github.com/tcarland)
* [Julie Ng](https://github.com/julie-ng)

So if you feel K9s is helping with your productivity while administering your Kubernetes clusters, please consider pitching in as it will go a long way in ensuring a thriving environment for this repo and our k9ers community at large.

Also please take some time and give a huge shoot out to all the good folks below that have spent time plowing thru the code to help improve K9s for all of us!

Thank you!!

---

## ♫ Sounds Behind The Release ♭

[Blue Christmas - Fats Domino](https://www.youtube.com/watch?v=7jeo09zAskc)
[Mele Kalikimaka - Bing Crosby](https://www.youtube.com/watch?v=hEvGKUXW0iI)
[Cause - Rodriguez -- Spreading The Holiday Cheer! 🤨](https://www.youtube.com/watch?v=oKFkc19T3Dk)

---

## 🎅🎄 !!Merry Christmas To All!! 🎄🎅

I hope you will take this time of the year to relax, re-source and spend quality time with your loved ones. I know it's been a `tad rocky` of recent ;( as I've gotten seriously slammed with work in the last few months...
The fine folks here on this channel have been nothing but kind, patient and willing to help, this humbles me! I feel truly blessed to be affiliated with our great `k9sers` community!
Next month, we'll celebrate our anniversary as we've started out in this venture back in Jan 2019 (Yikes!) so get crack'in and iron out those bow ties already!!

Best wishes for great health, happiness and continued success for 2022 to you all!!

-Fernand

---

## A Christmas Story...

As of this drop, we've added a new feature to override the sort column and order for a given Kubernetes resource. This feature piggy backs of custom column views and add a new attribute namely `sortColumn`. For example say you'd like to set the default sort for pods to age descending vs name/namespace, you can now do the following in your `views.yml` file in the k9s config directory:

NOTE: This file is live thus you can nav to your fav resource, change the column config and view the resource columns and sort changes... Woot!!

```yaml
k9s:
views:
v1/endpoints:
columns:
- NAME
- NAMESPACE
- ENDPOINTS
- AGE
v1/pods:
sortColumn: AGE:desc # => suffix [:asc|:desc] for ascending or descending order.
v1/services:
...
```
---
## Resolved Issues
* [Issue #1398](https://github.com/derailed/k9s/issues/1398) Pod logs containing brackets not in k9s logs output
* [Issue #1397](https://github.com/derailed/k9s/issues/1397) Regression: k9s no longer starts in current context namespace since v0.25.12
* [Issue #1358](https://github.com/derailed/k9s/issues/1358) Namespaces list is empty
* [Issue #956](https://github.com/derailed/k9s/issues/956) Feature request : Default column sort (by resource view)
---
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2021 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
29 changes: 16 additions & 13 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package cmd

import (
"fmt"
"os"
"runtime/debug"

"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/color"
"github.com/derailed/k9s/internal/config"
Expand All @@ -14,6 +11,8 @@ import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"os"
"runtime/debug"
)

const (
Expand Down Expand Up @@ -53,6 +52,17 @@ func Execute() {
}

func run(cmd *cobra.Command, args []string) {
config.EnsurePath(*k9sFlags.LogFile, config.DefaultDirMod)
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(*k9sFlags.LogFile, mod, config.DefaultFileMod)
if err != nil {
panic(err)
}
defer func() {
if file != nil {
_ = file.Close()
}
}()
defer func() {
if err := recover(); err != nil {
log.Error().Msgf("Boom! %v", err)
Expand All @@ -63,15 +73,6 @@ func run(cmd *cobra.Command, args []string) {
}
}()

config.EnsurePath(*k9sFlags.LogFile, config.DefaultDirMod)
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(*k9sFlags.LogFile, mod, config.DefaultFileMod)
defer func() {
_ = file.Close()
}()
if err != nil {
panic(err)
}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})

zerolog.SetGlobalLevel(parseLevel(*k9sFlags.LogLevel))
Expand Down Expand Up @@ -136,6 +137,8 @@ func loadConfiguration() *config.Config {

func parseLevel(level string) zerolog.Level {
switch level {
case "trace":
return zerolog.TraceLevel
case "debug":
return zerolog.DebugLevel
case "warn":
Expand All @@ -161,7 +164,7 @@ func initK9sFlags() {
k9sFlags.LogLevel,
"logLevel", "l",
config.DefaultLogLevel,
"Specify a log level (info, warn, debug, error)",
"Specify a log level (info, warn, debug, trace, error)",
)
rootCmd.Flags().StringVarP(
k9sFlags.LogFile,
Expand Down
2 changes: 2 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func makeSAR(ns, gvr string) *authorizationv1.SelfSubjectAccessReview {
ResourceAttributes: &authorizationv1.ResourceAttributes{
Namespace: ns,
Group: res.Group,
Version: res.Version,
Resource: res.Resource,
Subresource: spec.SubResource(),
},
Expand Down Expand Up @@ -162,6 +163,7 @@ func (a *APIClient) CanI(ns, gvr string, verbs []string) (auth bool, err error)
for _, v := range verbs {
sar.Spec.ResourceAttributes.Verb = v
resp, err := client.Create(ctx, sar, metav1.CreateOptions{})
log.Trace().Msgf("[CAN] %s(%s) %v <<%v>>", gvr, verbs, resp, err)
if err != nil {
log.Warn().Err(err).Msgf(" Dial Failed!")
a.cache.Add(key, false, cacheExpiry)
Expand Down
3 changes: 3 additions & 0 deletions internal/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const (
// AllNamespaces designates all namespaces.
AllNamespaces = ""

// DefaultNamespace designates the default namespace.
DefaultNamespace = "default"

// ClusterScope designates a resource is not namespaced.
ClusterScope = "-"

Expand Down
3 changes: 3 additions & 0 deletions internal/config/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ func (c *Cluster) Validate(conn client.Connection, ks KubeSettings) {
if c.Namespace == nil {
c.Namespace = NewNamespace()
}
if c.Namespace.Active == client.AllNamespaces {
c.Namespace.Active = client.NamespaceAll
}

if c.FeatureGates == nil {
c.FeatureGates = NewFeatureGates()
Expand Down
46 changes: 16 additions & 30 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,32 +90,24 @@ func (c *Config) Refine(flags *genericclioptions.ConfigFlags, k9sFlags *Flags, c
return fmt.Errorf("The specified context %q does not exists in kubeconfig", c.K9s.CurrentContext)
}
c.K9s.CurrentCluster = context.Cluster
c.K9s.ActivateCluster()
c.K9s.ActivateCluster(context.Namespace)

var cns string
if cl := c.K9s.ActiveCluster(); cl != nil && cl.Namespace != nil {
cns = cl.Namespace.Active
}
var ns string
var ns = client.DefaultNamespace
if k9sFlags != nil && IsBoolSet(k9sFlags.AllNamespaces) {
ns = client.NamespaceAll
} else if isSet(flags.Namespace) {
ns = *flags.Namespace
} else if context.Namespace != "" {
} else if isSet(flags.Context) {
ns = context.Namespace
if cns != "" {
ns = cns
}
} else {
ns = cns
ns = c.K9s.ActiveCluster().Namespace.Active
}

if ns != "" {
if err := c.SetActiveNamespace(ns); err != nil {
return err
}
flags.Namespace = &ns
if err := c.SetActiveNamespace(ns); err != nil {
return err
}
flags.Namespace = &ns

if isSet(flags.ClusterName) {
c.K9s.CurrentCluster = *flags.ClusterName
}
Expand Down Expand Up @@ -166,26 +158,21 @@ func (c *Config) ActiveNamespace() string {
// ValidateFavorites ensure favorite ns are legit.
func (c *Config) ValidateFavorites() {
cl := c.K9s.ActiveCluster()
if cl == nil {
cl = NewCluster()
}
cl.Validate(c.client, c.settings)
cl.Namespace.Validate(c.client, c.settings)
}

// FavNamespaces returns fav namespaces in the current cluster.
func (c *Config) FavNamespaces() []string {
cl := c.K9s.ActiveCluster()
if cl == nil {
return nil
}
return c.K9s.ActiveCluster().Namespace.Favorites

return cl.Namespace.Favorites
}

// SetActiveNamespace set the active namespace in the current cluster.
func (c *Config) SetActiveNamespace(ns string) error {
if c.K9s.ActiveCluster() != nil {
return c.K9s.ActiveCluster().Namespace.SetActive(ns, c.settings)
if cl := c.K9s.ActiveCluster(); cl != nil {
return cl.Namespace.SetActive(ns, c.settings)
}
err := errors.New("no active cluster. unable to set active namespace")
log.Error().Err(err).Msg("SetActiveNamespace")
Expand All @@ -195,11 +182,11 @@ func (c *Config) SetActiveNamespace(ns string) error {

// ActiveView returns the active view in the current cluster.
func (c *Config) ActiveView() string {
if c.K9s.ActiveCluster() == nil {
cl := c.K9s.ActiveCluster()
if cl == nil {
return defaultView
}

cmd := c.K9s.ActiveCluster().View.Active
cmd := cl.View.Active
if c.K9s.manualCommand != nil && *c.K9s.manualCommand != "" {
cmd = *c.K9s.manualCommand
}
Expand All @@ -209,8 +196,7 @@ func (c *Config) ActiveView() string {

// SetActiveView set the currently cluster active view.
func (c *Config) SetActiveView(view string) {
cl := c.K9s.ActiveCluster()
if cl != nil {
if cl := c.K9s.ActiveCluster(); cl != nil {
cl.View.Active = view
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestConfigRefine(t *testing.T) {
issue: false,
context: "test1",
cluster: "cluster1",
namespace: "default",
namespace: "ns1",
},
"overrideNS": {
flags: &genericclioptions.ConfigFlags{
Expand Down
13 changes: 7 additions & 6 deletions internal/config/k9s.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,31 @@ func NewK9s() *K9s {
}

// ActivateCluster initializes the active cluster is not present.
func (k *K9s) ActivateCluster() {
func (k *K9s) ActivateCluster(ns string) {
if _, ok := k.Clusters[k.CurrentCluster]; ok {
return
}
k.Clusters[k.CurrentCluster] = NewCluster()
cl := NewCluster()
cl.Namespace.Active = ns
k.Clusters[k.CurrentCluster] = cl
}

// OverrideRefreshRate set the refresh rate manually.
func (k *K9s) OverrideRefreshRate(r int) {
k.manualRefreshRate = r
}

// OverrideHeadless set the headlessness manually.
// OverrideHeadless toggle the header manually.
func (k *K9s) OverrideHeadless(b bool) {
k.manualHeadless = &b
}

// OverrideLogoless set the logolessness manually.
// OverrideLogoless toggle the k9s logo manually.
func (k *K9s) OverrideLogoless(b bool) {
k.manualLogoless = &b
}

// OverrideCrumbsless set the crumbslessness manually.
// OverrideCrumbsless tooh the crumbslessness manually.
func (k *K9s) OverrideCrumbsless(b bool) {
k.manualCrumbsless = &b
}
Expand Down Expand Up @@ -154,7 +156,6 @@ func (k *K9s) ActiveCluster() *Cluster {
if k.Clusters == nil {
k.Clusters = map[string]*Cluster{}
}

if c, ok := k.Clusters[k.CurrentCluster]; ok {
return c
}
Expand Down
2 changes: 1 addition & 1 deletion internal/config/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Namespace struct {
func NewNamespace() *Namespace {
return &Namespace{
Active: defaultNS,
Favorites: []string{"default"},
Favorites: []string{defaultNS},
}
}

Expand Down
3 changes: 2 additions & 1 deletion internal/config/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type ViewConfigListener interface {

// ViewSetting represents a view configuration.
type ViewSetting struct {
Columns []string `yaml:"columns"`
Columns []string `yaml:"columns"`
SortColumn string `yaml:"sortColumn"`
}

// ViewSettings represent a collection of view configurations.
Expand Down
2 changes: 1 addition & 1 deletion internal/dao/log_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (o *LogOptions) ToLogItem(bytes []byte) *LogItem {

func (o *LogOptions) ToErrLogItem(err error) *LogItem {
t := time.Now().UTC().Format(time.RFC3339Nano)
item := NewLogItem([]byte(fmt.Sprintf("%s [red::b]%s\n", t, err)))
item := NewLogItem([]byte(fmt.Sprintf("%s [orange::b]%s[::-]\n", t, err)))
item.IsError = true
return item
}
Loading

0 comments on commit fc8ffe5

Please sign in to comment.