diff --git a/.goreleaser.yml b/.goreleaser.yml
index b5357731..f74f5942 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -83,7 +83,6 @@ snapcraft:
# confinement: strict
apps:
k9s:
- # plugs: ["home", "network"]
plugs: ["home", "network", "kube-config"]
plugs:
kube-config:
diff --git a/README.md b/README.md
index 73921e0b..62b150c0 100644
--- a/README.md
+++ b/README.md
@@ -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)
---
diff --git a/change_logs/release_0.7.2.md b/change_logs/release_0.7.2.md
new file mode 100644
index 00000000..0b3361de
--- /dev/null
+++ b/change_logs/release_0.7.2.md
@@ -0,0 +1,28 @@
+
+
+# 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)
+
+
+---
+
+
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
diff --git a/internal/views/container.go b/internal/views/container.go
index 5053176d..55511bcc 100644
--- a/internal/views/container.go
+++ b/internal/views/container.go
@@ -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 {
diff --git a/internal/views/helpers.go b/internal/views/helpers.go
index 11b42734..e06c86b0 100644
--- a/internal/views/helpers.go
+++ b/internal/views/helpers.go
@@ -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)
diff --git a/internal/views/helpers_test.go b/internal/views/helpers_test.go
index c8a5d6ea..93149f03 100644
--- a/internal/views/helpers_test.go
+++ b/internal/views/helpers_test.go
@@ -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))
+ })
+ }
+}
diff --git a/internal/watch/informer.go b/internal/watch/informer.go
index 4185ed09..aeabffb6 100644
--- a/internal/watch/informer.go
+++ b/internal/watch/informer.go
@@ -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
}