Merge pull request #70931 from m1kola/port-forward-consistency

Fixes inconsistent behaviour in portforward
This commit is contained in:
Kubernetes Prow Robot 2019-02-10 19:37:27 -08:00 committed by GitHub
commit 162b79d2ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 5 deletions

View File

@ -120,7 +120,7 @@ func NewCmdPortForward(f cmdutil.Factory, streams genericclioptions.IOStreams) *
}, },
} }
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodPortForwardWaitTimeout) cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodPortForwardWaitTimeout)
cmd.Flags().StringSliceVar(&opts.Address, "address", []string{"localhost"}, "Addresses to listen on (comma separated)") cmd.Flags().StringSliceVar(&opts.Address, "address", []string{"localhost"}, "Addresses to listen on (comma separated). Only accepts IP addresses or localhost as a value. When localhost is supplied, kubectl will try to bind on both 127.0.0.1 and ::1 and will fail if neither of these addresses are available to bind.")
// TODO support UID // TODO support UID
return cmd return cmd
} }

View File

@ -23,6 +23,7 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -122,10 +123,14 @@ func parseAddresses(addressesToParse []string) ([]listenAddress, error) {
parsed := make(map[string]listenAddress) parsed := make(map[string]listenAddress)
for _, address := range addressesToParse { for _, address := range addressesToParse {
if address == "localhost" { if address == "localhost" {
ip := listenAddress{address: "127.0.0.1", protocol: "tcp4", failureMode: "all"} if _, exists := parsed["127.0.0.1"]; !exists {
parsed[ip.address] = ip ip := listenAddress{address: "127.0.0.1", protocol: "tcp4", failureMode: "all"}
ip = listenAddress{address: "::1", protocol: "tcp6", failureMode: "all"} parsed[ip.address] = ip
parsed[ip.address] = ip }
if _, exists := parsed["::1"]; !exists {
ip := listenAddress{address: "::1", protocol: "tcp6", failureMode: "all"}
parsed[ip.address] = ip
}
} else if net.ParseIP(address).To4() != nil { } else if net.ParseIP(address).To4() != nil {
parsed[address] = listenAddress{address: address, protocol: "tcp4", failureMode: "any"} parsed[address] = listenAddress{address: address, protocol: "tcp4", failureMode: "any"}
} else if net.ParseIP(address) != nil { } else if net.ParseIP(address) != nil {
@ -140,6 +145,9 @@ func parseAddresses(addressesToParse []string) ([]listenAddress, error) {
addresses[id] = v addresses[id] = v
id++ id++
} }
// Sort addresses before returning to get a stable order
sort.Slice(addresses, func(i, j int) bool { return addresses[i].address < addresses[j].address })
return addresses, nil return addresses, nil
} }

View File

@ -83,6 +83,62 @@ func TestParsePortsAndNew(t *testing.T) {
{protocol: "tcp6", address: "::1", failureMode: "all"}, {protocol: "tcp6", address: "::1", failureMode: "all"},
}, },
}, },
{
input: []string{"5000:5000"},
addresses: []string{"localhost", "::1"},
expectedPorts: []ForwardedPort{
{5000, 5000},
},
expectedAddresses: []listenAddress{
{protocol: "tcp4", address: "127.0.0.1", failureMode: "all"},
{protocol: "tcp6", address: "::1", failureMode: "any"},
},
},
{
input: []string{"5000:5000"},
addresses: []string{"localhost", "127.0.0.1", "::1"},
expectedPorts: []ForwardedPort{
{5000, 5000},
},
expectedAddresses: []listenAddress{
{protocol: "tcp4", address: "127.0.0.1", failureMode: "any"},
{protocol: "tcp6", address: "::1", failureMode: "any"},
},
},
{
input: []string{"5000:5000"},
addresses: []string{"localhost", "127.0.0.1", "10.10.10.1"},
expectedPorts: []ForwardedPort{
{5000, 5000},
},
expectedAddresses: []listenAddress{
{protocol: "tcp4", address: "127.0.0.1", failureMode: "any"},
{protocol: "tcp6", address: "::1", failureMode: "all"},
{protocol: "tcp4", address: "10.10.10.1", failureMode: "any"},
},
},
{
input: []string{"5000:5000"},
addresses: []string{"127.0.0.1", "::1", "localhost"},
expectedPorts: []ForwardedPort{
{5000, 5000},
},
expectedAddresses: []listenAddress{
{protocol: "tcp4", address: "127.0.0.1", failureMode: "any"},
{protocol: "tcp6", address: "::1", failureMode: "any"},
},
},
{
input: []string{"5000:5000"},
addresses: []string{"10.0.0.1", "127.0.0.1"},
expectedPorts: []ForwardedPort{
{5000, 5000},
},
expectedAddresses: []listenAddress{
{protocol: "tcp4", address: "10.0.0.1", failureMode: "any"},
{protocol: "tcp4", address: "127.0.0.1", failureMode: "any"},
},
},
{ {
input: []string{"5000", "5000:5000", "8888:5000", "5000:8888", ":5000", "0:5000"}, input: []string{"5000", "5000:5000", "8888:5000", "5000:8888", ":5000", "0:5000"},
addresses: []string{"127.0.0.1", "::1"}, addresses: []string{"127.0.0.1", "::1"},