parent
49855b6f80
commit
a952806eba
2
Makefile
2
Makefile
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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": "/"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue