Fix for issue #202 + make node access optional
parent
999e4806b5
commit
f469070b35
|
|
@ -83,7 +83,6 @@ snapcraft:
|
|||
# confinement: strict
|
||||
apps:
|
||||
k9s:
|
||||
# plugs: ["home", "network"]
|
||||
plugs: ["home", "network", "kube-config"]
|
||||
plugs:
|
||||
kube-config:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ for changes and offers subsequent commands to interact with observed resources.
|
|||
[](https://travis-ci.com/derailed/k9s)
|
||||
[](https://github.com/derailed/k9s/releases)
|
||||
[](https://github.com/mum4k/termdash/blob/master/LICENSE)
|
||||
<!-- [](https://snapcraft.io/k9s) -->
|
||||
[](https://snapcraft.io/k9s)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
|
||||
|
||||
# Release v0.7.2
|
||||
|
||||
## Notes
|
||||
|
||||
Thank you to all that contributed with flushing out issues with 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 is as always very much appreciated!
|
||||
|
||||
Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||
|
||||
---
|
||||
|
||||
## Change Logs
|
||||
|
||||
### Bug Fix Drop
|
||||
|
||||
Removed requirement that enforces node access. In the case RBAC rules are in effect and user does not have enough RBAC-Fu to list/watch cluster nodes.
|
||||
|
||||
---
|
||||
|
||||
## Resolved Bugs/Features
|
||||
|
||||
+ [Issue #202](https://github.com/derailed/k9s/issues/202)
|
||||
|
||||
|
||||
---
|
||||
|
||||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
|
@ -134,9 +134,18 @@ func (v *containerView) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
v.app.flash().err(errors.New("Container exposes no ports"))
|
||||
return nil
|
||||
}
|
||||
port := strings.TrimSpace(ports[0])
|
||||
|
||||
var port string
|
||||
for _, p := range ports {
|
||||
log.Debug().Msgf("Checking port %q", p)
|
||||
if !isTCPPort(p) {
|
||||
continue
|
||||
}
|
||||
port = strings.TrimSpace(p)
|
||||
break
|
||||
}
|
||||
if port == "" {
|
||||
v.app.flash().err(errors.New("Container exposed no ports"))
|
||||
v.app.flash().err(errors.New("No valid TCP port found on this container"))
|
||||
return nil
|
||||
}
|
||||
f := tview.NewForm()
|
||||
|
|
@ -148,16 +157,16 @@ func (v *containerView) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
SetFieldTextColor(tcell.ColorOrange)
|
||||
|
||||
f1, f2 := port, port
|
||||
f.AddInputField("Pod Port:", f1, 10, nil, func(changed string) {
|
||||
f.AddInputField("Pod Port:", f1, 20, nil, func(changed string) {
|
||||
f1 = changed
|
||||
})
|
||||
f.AddInputField("Local Port:", f2, 10, nil, func(changed string) {
|
||||
f.AddInputField("Local Port:", f2, 20, nil, func(changed string) {
|
||||
f2 = changed
|
||||
})
|
||||
|
||||
f.AddButton("OK", func() {
|
||||
pf := k8s.NewPortForward(v.app.conn(), &log.Logger)
|
||||
ports := []string{f2 + ":" + f1}
|
||||
ports := []string{stripPort(f2) + ":" + stripPort(f1)}
|
||||
co := strings.TrimSpace(v.getTV().GetCell(v.selectedRow, 0).Text)
|
||||
fw, err := pf.Start(*v.path, co, ports)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,20 @@ const (
|
|||
minusSign = "↓"
|
||||
)
|
||||
|
||||
func isTCPPort(p string) bool {
|
||||
return !strings.Contains(p, "UDP")
|
||||
}
|
||||
|
||||
// StripPort removes the named port id if present.
|
||||
func stripPort(p string) string {
|
||||
tokens := strings.Split(p, ":")
|
||||
if len(tokens) == 2 {
|
||||
return strings.Replace(tokens[1], "╱UDP", "", 1)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// ContainerID computes container ID based on ns/po/co.
|
||||
func containerID(path, co string) string {
|
||||
ns, n := namespaced(path)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package views
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
|
|
@ -87,3 +88,26 @@ func TestContainerID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripPort(t *testing.T) {
|
||||
uu := map[string]struct {
|
||||
port, e string
|
||||
}{
|
||||
"full": {
|
||||
"fred:8000", "8000",
|
||||
},
|
||||
"port": {
|
||||
"8000", "8000",
|
||||
},
|
||||
"protocol": {
|
||||
"dns:53╱UDP", "53",
|
||||
},
|
||||
}
|
||||
|
||||
for k, u := range uu {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
fmt.Println("TCP?", u.port, isTCPPort(u.port))
|
||||
assert.Equal(t, u.e, stripPort(u.port))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,11 +86,14 @@ func (i *Informer) init(ns string) {
|
|||
i.initOnce.Do(func() {
|
||||
po := NewPod(i.client, ns)
|
||||
i.informers = map[string]StoreInformer{
|
||||
NodeIndex: NewNode(i.client),
|
||||
PodIndex: po,
|
||||
ContainerIndex: NewContainer(po),
|
||||
}
|
||||
|
||||
if i.client.CanIAccess("", "", "nodes", []string{"list", "watch"}) {
|
||||
i.informers[NodeIndex] = NewNode(i.client)
|
||||
}
|
||||
|
||||
if !i.client.HasMetrics() {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue