diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 8678dbb9..4f4b7aac 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,7 +1,7 @@ { "ImportPath": "k8s.io/client-go", "GoVersion": "go1.11", - "GodepVersion": "v80-k8s-r1", + "GodepVersion": "v80", "Packages": [ "./..." ], @@ -412,207 +412,207 @@ }, { "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/equality", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/meta", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/resource", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/labels", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/selection", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/types", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/cache", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/clock", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/diff", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/errors", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/framer", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/intstr", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/json", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/naming", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/net", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/runtime", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/sets", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/wait", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/yaml", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/version", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/pkg/watch", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", - "Rev": "f951fa7b8c72cf726656de66d834a518359ce6e7" + "Rev": "dcb391cde5ca0298013d43336817d20b74650702" }, { "ImportPath": "k8s.io/klog", diff --git a/tools/portforward/portforward.go b/tools/portforward/portforward.go index 357680ed..a50a9973 100644 --- a/tools/portforward/portforward.go +++ b/tools/portforward/portforward.go @@ -205,8 +205,9 @@ func (pf *PortForwarder) forward() error { var err error listenSuccess := false - for _, port := range pf.ports { - err = pf.listenOnPort(&port) + for i := range pf.ports { + port := &pf.ports[i] + err = pf.listenOnPort(port) switch { case err == nil: listenSuccess = true diff --git a/tools/portforward/portforward_test.go b/tools/portforward/portforward_test.go index dd8d4fd5..b39fa504 100644 --- a/tools/portforward/portforward_test.go +++ b/tools/portforward/portforward_test.go @@ -18,11 +18,13 @@ package portforward import ( "net" + "net/http" "os" "reflect" "sort" "strings" "testing" + "time" "k8s.io/apimachinery/pkg/util/httpstream" ) @@ -39,6 +41,37 @@ func (d *fakeDialer) Dial(protocols ...string) (httpstream.Connection, string, e return d.conn, d.negotiatedProtocol, d.err } +type fakeConnection struct { + closed bool + closeChan chan bool +} + +func newFakeConnection() httpstream.Connection { + return &fakeConnection{ + closeChan: make(chan bool), + } +} + +func (c *fakeConnection) CreateStream(headers http.Header) (httpstream.Stream, error) { + return nil, nil +} + +func (c *fakeConnection) Close() error { + if !c.closed { + c.closed = true + close(c.closeChan) + } + return nil +} + +func (c *fakeConnection) CloseChan() <-chan bool { + return c.closeChan +} + +func (c *fakeConnection) SetIdleTimeout(timeout time.Duration) { + // no-op +} + func TestParsePortsAndNew(t *testing.T) { tests := []struct { input []string @@ -310,3 +343,46 @@ func TestGetListener(t *testing.T) { } } + +func TestGetPortsReturnsDynamicallyAssignedLocalPort(t *testing.T) { + dialer := &fakeDialer{ + conn: newFakeConnection(), + } + + stopChan := make(chan struct{}) + readyChan := make(chan struct{}) + errChan := make(chan error) + + defer func() { + close(stopChan) + + forwardErr := <-errChan + if forwardErr != nil { + t.Fatalf("ForwardPorts returned error: %s", forwardErr) + } + }() + + pf, err := New(dialer, []string{":5000"}, stopChan, readyChan, os.Stdout, os.Stderr) + + if err != nil { + t.Fatalf("error while calling New: %s", err) + } + + go func() { + errChan <- pf.ForwardPorts() + close(errChan) + }() + + <-pf.Ready + + ports, err := pf.GetPorts() + + if len(ports) != 1 { + t.Fatalf("expected 1 port, got %d", len(ports)) + } + + port := ports[0] + if port.Local == 0 { + t.Fatalf("local port is 0, expected != 0") + } +}