derailed 2020-11-10 08:17:50 -07:00
parent 49855b6f80
commit a952806eba
12 changed files with 52 additions and 11 deletions

View File

@ -18,7 +18,7 @@ cover: ## Run test coverage suite
build: ## Builds the CLI build: ## Builds the CLI
@go build \ @go build \
-ldflags "-w -s -X ${PACKAGE}/cmd.version=v${VERSION} -X ${PACKAGE}/cmd.commit=${GIT} -X ${PACKAGE}/cmd.date=${DATE}" \ -ldflags "-w -s -X ${PACKAGE}/cmd.version=${VERSION} -X ${PACKAGE}/cmd.commit=${GIT} -X ${PACKAGE}/cmd.date=${DATE}" \
-a -tags netgo -o execs/${NAME} main.go -a -tags netgo -o execs/${NAME} main.go
kubectl-stable-version: ## Get kubectl latest stable version kubectl-stable-version: ## Get kubectl latest stable version

View File

@ -0,0 +1,29 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
# Release v0.23.10
## 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 [sponsorhip 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)
---
## Maintenance Release!
---
## Resolved Issues/Features
* [Issue #933](https://github.com/derailed/k9s/issues/933) Unable to cordon node starting in v0.23.8
* [Issue #932](https://github.com/derailed/k9s/issues/932) Won't start if api.github.com is inaccessible
* [Issue #931](https://github.com/derailed/k9s/issues/931) Describe ingress not showing labels
## Resolved PRs
---
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -421,7 +421,7 @@ func (s *Styles) AddListener(l StyleListener) {
s.listeners = append(s.listeners, l) s.listeners = append(s.listeners, l)
} }
// RemoveListener unregister a listener. // RemoveListener removes a listener.
func (s *Styles) RemoveListener(l StyleListener) { func (s *Styles) RemoveListener(l StyleListener) {
victim := -1 victim := -1
for i, lis := range s.listeners { for i, lis := range s.listeners {

View File

@ -8,7 +8,6 @@ import (
"github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/client"
"github.com/rs/zerolog/log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
@ -93,7 +92,6 @@ func (g *Generic) ToYAML(path string, showManaged bool) (string, error) {
// Delete deletes a resource. // Delete deletes a resource.
func (g *Generic) Delete(path string, cascade, force bool) error { func (g *Generic) Delete(path string, cascade, force bool) error {
log.Debug().Msgf("DELETE %q -- %t:%t", path, cascade, force)
ns, n := client.Namespaced(path) ns, n := client.Namespaced(path)
auth, err := g.Client().CanI(ns, g.gvr.String(), []string{client.DeleteVerb}) auth, err := g.Client().CanI(ns, g.gvr.String(), []string{client.DeleteVerb})
if err != nil { if err != nil {

View File

@ -222,7 +222,7 @@ func FetchNode(ctx context.Context, f Factory, path string) (*v1.Node, error) {
return nil, fmt.Errorf("user is not authorized to list nodes") return nil, fmt.Errorf("user is not authorized to list nodes")
} }
o, err := f.Get("v1/nodes", path, false, labels.Everything()) o, err := f.Get("v1/nodes", client.FQN(client.ClusterScope, path), false, labels.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -40,6 +40,9 @@ func (*SemVer) parse(version string) (major, minor, patch int) {
// Normalize ensures the version starts with a v. // Normalize ensures the version starts with a v.
func NormalizeVersion(version string) string { func NormalizeVersion(version string) string {
if version == "" {
return version
}
if version[0] == 'v' { if version[0] == 'v' {
return version return version
} }

View File

@ -101,6 +101,13 @@ func blank(s []string) bool {
return true return true
} }
func strpToStr(p *string) string {
if p == nil || *p == "" {
return MissingValue
}
return *p
}
// Join a slice of strings, skipping blanks. // Join a slice of strings, skipping blanks.
func join(a []string, sep string) string { func join(a []string, sep string) string {
switch len(a) { switch len(a) {

View File

@ -24,10 +24,11 @@ func (Ingress) Header(ns string) Header {
return Header{ return Header{
HeaderColumn{Name: "NAMESPACE"}, HeaderColumn{Name: "NAMESPACE"},
HeaderColumn{Name: "NAME"}, HeaderColumn{Name: "NAME"},
HeaderColumn{Name: "CLASS"},
HeaderColumn{Name: "HOSTS"}, HeaderColumn{Name: "HOSTS"},
HeaderColumn{Name: "ADDRESS"}, HeaderColumn{Name: "ADDRESS"},
HeaderColumn{Name: "PORT"}, HeaderColumn{Name: "PORTS"},
HeaderColumn{Name: "VALID", Wide: true}, HeaderColumn{Name: "LABELS", Wide: true},
HeaderColumn{Name: "AGE", Time: true, Decorator: AgeDecorator}, HeaderColumn{Name: "AGE", Time: true, Decorator: AgeDecorator},
} }
} }
@ -48,10 +49,11 @@ func (i Ingress) Render(o interface{}, ns string, r *Row) error {
r.Fields = Fields{ r.Fields = Fields{
ing.Namespace, ing.Namespace,
ing.Name, ing.Name,
strpToStr(ing.Spec.IngressClassName),
toHosts(ing.Spec.Rules), toHosts(ing.Spec.Rules),
toAddress(ing.Status.LoadBalancer), toAddress(ing.Status.LoadBalancer),
toTLSPorts(ing.Spec.TLS), toTLSPorts(ing.Spec.TLS),
"", mapToStr(ing.Labels),
toAge(ing.ObjectMeta.CreationTimestamp), toAge(ing.ObjectMeta.CreationTimestamp),
} }

View File

@ -13,5 +13,5 @@ func TestIngressRender(t *testing.T) {
c.Render(load(t, "ing"), "", &r) c.Render(load(t, "ing"), "", &r)
assert.Equal(t, "default/test-ingress", r.ID) assert.Equal(t, "default/test-ingress", r.ID)
assert.Equal(t, render.Fields{"default", "test-ingress", "*", "", "80"}, r.Fields[:5]) assert.Equal(t, render.Fields{"default", "test-ingress", "<none>", "*", "", "80", "role=ingress"}, r.Fields[:7])
} }

View File

@ -2,6 +2,9 @@
"apiVersion": "extensions/v1beta1", "apiVersion": "extensions/v1beta1",
"kind": "Ingress", "kind": "Ingress",
"metadata": { "metadata": {
"labels": {
"role": "ingress"
},
"annotations": { "annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"extensions/v1beta1\",\"kind\":\"Ingress\",\"metadata\":{\"annotations\":{\"nginx.ingress.kubernetes.io/rewrite-target\":\"/\"},\"name\":\"test-ingress\",\"namespace\":\"default\"},\"spec\":{\"rules\":[{\"http\":{\"paths\":[{\"backend\":{\"serviceName\":\"test\",\"servicePort\":80},\"path\":\"/testpath\"}]}}]}}\n", "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"extensions/v1beta1\",\"kind\":\"Ingress\",\"metadata\":{\"annotations\":{\"nginx.ingress.kubernetes.io/rewrite-target\":\"/\"},\"name\":\"test-ingress\",\"namespace\":\"default\"},\"spec\":{\"rules\":[{\"http\":{\"paths\":[{\"backend\":{\"serviceName\":\"test\",\"servicePort\":80},\"path\":\"/testpath\"}]}}]}}\n",
"nginx.ingress.kubernetes.io/rewrite-target": "/" "nginx.ingress.kubernetes.io/rewrite-target": "/"

View File

@ -269,7 +269,6 @@ var EOL = []byte{'\n'}
// Flush write logs to viewer. // Flush write logs to viewer.
func (l *Log) Flush(lines [][]byte) { func (l *Log) Flush(lines [][]byte) {
log.Debug().Msgf("LOG-FLUSH %d", len(lines))
if !l.indicator.AutoScroll() { if !l.indicator.AutoScroll() {
return return
} }

View File

@ -47,7 +47,7 @@ func (n *Node) bindDangerousKeys(aa ui.KeyActions) {
} }
func (n *Node) bindKeys(aa ui.KeyActions) { func (n *Node) bindKeys(aa ui.KeyActions) {
aa.Delete(ui.KeySpace, tcell.KeyCtrlSpace, tcell.KeyCtrlD) aa.Delete(ui.KeySpace, tcell.KeyCtrlSpace)
if !n.App().Config.K9s.IsReadOnly() { if !n.App().Config.K9s.IsReadOnly() {
n.bindDangerousKeys(aa) n.bindDangerousKeys(aa)