Unverified Commit f9f8dc30 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #52748 from leblancd/v6_e2e_host_port

Automatic merge from submit-queue (batch tested with PRs 52748, 56623). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add brackets around IPv6 addrs in e2e test IP:port endpoints There are several locations in the e2e tests where endpoints of the form IPv6:port use IPv6 addresses directly, without surrounding brackets. Brackets are required around IPv6 addresses in this case, in order to distinguish the colons in the IPv6 address from the colon immediately preceding the port. Also, wherever the curl command might be used with an IPv6 address surrounded in brackets, the "-g" argument is added to the curl command line arguments so that the brackets can be interpreted correctly. fixes #52746 **What this PR does / why we need it**: This PR adds brackets around IPv6 addresses when they appear as part of an IPv6-addr:port endpoint in the e2e tests. This is needed because any connections that attempt to use IPv6-addr:port endpoint without brackets surrounding the IPv6-addr will fail. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #52746 **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
parents 77a2a646 2827b7ff
...@@ -179,9 +179,12 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String { ...@@ -179,9 +179,12 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String {
// more for maxTries. Use this if you want to eg: fail a readiness check on a // more for maxTries. Use this if you want to eg: fail a readiness check on a
// pod and confirm it doesn't show up as an endpoint. // pod and confirm it doesn't show up as an endpoint.
func (config *NetworkingTestConfig) DialFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, maxTries, minTries int, expectedEps sets.String) { func (config *NetworkingTestConfig) DialFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, maxTries, minTries int, expectedEps sets.String) {
cmd := fmt.Sprintf("curl -q -s 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'", ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHttpPort))
containerIP, // The current versions of curl included in CentOS and RHEL distros
containerHttpPort, // misinterpret square brackets around IPv6 as globbing, so use the -g
// argument to disable globbing to handle the IPv6 case.
cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'",
ipPort,
protocol, protocol,
targetIP, targetIP,
targetPort) targetPort)
...@@ -234,9 +237,12 @@ func (config *NetworkingTestConfig) GetEndpointsFromTestContainer(protocol, targ ...@@ -234,9 +237,12 @@ func (config *NetworkingTestConfig) GetEndpointsFromTestContainer(protocol, targ
// - tries is the number of curl attempts. If this many attempts pass and // - tries is the number of curl attempts. If this many attempts pass and
// we don't see any endpoints, the test fails. // we don't see any endpoints, the test fails.
func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, tries int) (sets.String, error) { func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, tries int) (sets.String, error) {
cmd := fmt.Sprintf("curl -q -s 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'", ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHttpPort))
containerIP, // The current versions of curl included in CentOS and RHEL distros
containerHttpPort, // misinterpret square brackets around IPv6 as globbing, so use the -g
// argument to disable globbing to handle the IPv6 case.
cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'",
ipPort,
protocol, protocol,
targetIP, targetIP,
targetPort) targetPort)
...@@ -289,7 +295,11 @@ func (config *NetworkingTestConfig) DialFromNode(protocol, targetIP string, targ ...@@ -289,7 +295,11 @@ func (config *NetworkingTestConfig) DialFromNode(protocol, targetIP string, targ
// busybox timeout doesn't support non-integer values. // busybox timeout doesn't support non-integer values.
cmd = fmt.Sprintf("echo 'hostName' | timeout -t 2 nc -w 1 -u %s %d", targetIP, targetPort) cmd = fmt.Sprintf("echo 'hostName' | timeout -t 2 nc -w 1 -u %s %d", targetIP, targetPort)
} else { } else {
cmd = fmt.Sprintf("timeout -t 15 curl -q -s --connect-timeout 1 http://%s:%d/hostName", targetIP, targetPort) ipPort := net.JoinHostPort(targetIP, strconv.Itoa(targetPort))
// The current versions of curl included in CentOS and RHEL distros
// misinterpret square brackets around IPv6 as globbing, so use the -g
// argument to disable globbing to handle the IPv6 case.
cmd = fmt.Sprintf("timeout -t 15 curl -g -q -s --connect-timeout 1 http://%s/hostName", ipPort)
} }
// TODO: This simply tells us that we can reach the endpoints. Check that // TODO: This simply tells us that we can reach the endpoints. Check that
...@@ -736,7 +746,8 @@ func TestReachableHTTPWithContentTimeout(ip string, port int, request string, ex ...@@ -736,7 +746,8 @@ func TestReachableHTTPWithContentTimeout(ip string, port int, request string, ex
func TestReachableHTTPWithContentTimeoutWithRetriableErrorCodes(ip string, port int, request string, expect string, content *bytes.Buffer, retriableErrCodes []int, timeout time.Duration) (bool, error) { func TestReachableHTTPWithContentTimeoutWithRetriableErrorCodes(ip string, port int, request string, expect string, content *bytes.Buffer, retriableErrCodes []int, timeout time.Duration) (bool, error) {
url := fmt.Sprintf("http://%s:%d%s", ip, port, request) ipPort := net.JoinHostPort(ip, strconv.Itoa(port))
url := fmt.Sprintf("http://%s%s", ipPort, request)
if ip == "" { if ip == "" {
Failf("Got empty IP for reachability check (%s)", url) Failf("Got empty IP for reachability check (%s)", url)
return false, nil return false, nil
...@@ -783,7 +794,8 @@ func TestNotReachableHTTP(ip string, port int) (bool, error) { ...@@ -783,7 +794,8 @@ func TestNotReachableHTTP(ip string, port int) (bool, error) {
} }
func TestNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) (bool, error) { func TestNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) (bool, error) {
url := fmt.Sprintf("http://%s:%d", ip, port) ipPort := net.JoinHostPort(ip, strconv.Itoa(port))
url := fmt.Sprintf("http://%s", ipPort)
if ip == "" { if ip == "" {
Failf("Got empty IP for non-reachability check (%s)", url) Failf("Got empty IP for non-reachability check (%s)", url)
return false, nil return false, nil
...@@ -805,7 +817,8 @@ func TestNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) (bo ...@@ -805,7 +817,8 @@ func TestNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) (bo
} }
func TestReachableUDP(ip string, port int, request string, expect string) (bool, error) { func TestReachableUDP(ip string, port int, request string, expect string) (bool, error) {
uri := fmt.Sprintf("udp://%s:%d", ip, port) ipPort := net.JoinHostPort(ip, strconv.Itoa(port))
uri := fmt.Sprintf("udp://%s", ipPort)
if ip == "" { if ip == "" {
Failf("Got empty IP for reachability check (%s)", uri) Failf("Got empty IP for reachability check (%s)", uri)
return false, nil return false, nil
...@@ -817,9 +830,9 @@ func TestReachableUDP(ip string, port int, request string, expect string) (bool, ...@@ -817,9 +830,9 @@ func TestReachableUDP(ip string, port int, request string, expect string) (bool,
Logf("Testing UDP reachability of %v", uri) Logf("Testing UDP reachability of %v", uri)
con, err := net.Dial("udp", ip+":"+strconv.Itoa(port)) con, err := net.Dial("udp", ipPort)
if err != nil { if err != nil {
return false, fmt.Errorf("Failed to dial %s:%d: %v", ip, port, err) return false, fmt.Errorf("Failed to dial %s: %v", ipPort, err)
} }
_, err = con.Write([]byte(fmt.Sprintf("%s\n", request))) _, err = con.Write([]byte(fmt.Sprintf("%s\n", request)))
...@@ -848,7 +861,8 @@ func TestReachableUDP(ip string, port int, request string, expect string) (bool, ...@@ -848,7 +861,8 @@ func TestReachableUDP(ip string, port int, request string, expect string) (bool,
} }
func TestNotReachableUDP(ip string, port int, request string) (bool, error) { func TestNotReachableUDP(ip string, port int, request string) (bool, error) {
uri := fmt.Sprintf("udp://%s:%d", ip, port) ipPort := net.JoinHostPort(ip, strconv.Itoa(port))
uri := fmt.Sprintf("udp://%s", ipPort)
if ip == "" { if ip == "" {
Failf("Got empty IP for reachability check (%s)", uri) Failf("Got empty IP for reachability check (%s)", uri)
return false, nil return false, nil
...@@ -860,7 +874,7 @@ func TestNotReachableUDP(ip string, port int, request string) (bool, error) { ...@@ -860,7 +874,7 @@ func TestNotReachableUDP(ip string, port int, request string) (bool, error) {
Logf("Testing UDP non-reachability of %v", uri) Logf("Testing UDP non-reachability of %v", uri)
con, err := net.Dial("udp", ip+":"+strconv.Itoa(port)) con, err := net.Dial("udp", ipPort)
if err != nil { if err != nil {
Logf("Confirmed that %s is not reachable", uri) Logf("Confirmed that %s is not reachable", uri)
return true, nil return true, nil
......
...@@ -19,6 +19,7 @@ package framework ...@@ -19,6 +19,7 @@ package framework
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"net"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
...@@ -878,7 +879,8 @@ func (j *ServiceTestJig) GetHTTPContent(host string, port int, timeout time.Dura ...@@ -878,7 +879,8 @@ func (j *ServiceTestJig) GetHTTPContent(host string, port int, timeout time.Dura
} }
func testHTTPHealthCheckNodePort(ip string, port int, request string) (bool, error) { func testHTTPHealthCheckNodePort(ip string, port int, request string) (bool, error) {
url := fmt.Sprintf("http://%s:%d%s", ip, port, request) ipPort := net.JoinHostPort(ip, strconv.Itoa(port))
url := fmt.Sprintf("http://%s%s", ipPort, request)
if ip == "" || port == 0 { if ip == "" || port == 0 {
Failf("Got empty IP for reachability check (%s)", url) Failf("Got empty IP for reachability check (%s)", url)
return false, fmt.Errorf("Invalid input ip or port") return false, fmt.Errorf("Invalid input ip or port")
...@@ -1292,8 +1294,9 @@ func VerifyServeHostnameServiceUp(c clientset.Interface, ns, host string, expect ...@@ -1292,8 +1294,9 @@ func VerifyServeHostnameServiceUp(c clientset.Interface, ns, host string, expect
// Loop a bunch of times - the proxy is randomized, so we want a good // Loop a bunch of times - the proxy is randomized, so we want a good
// chance of hitting each backend at least once. // chance of hitting each backend at least once.
buildCommand := func(wget string) string { buildCommand := func(wget string) string {
return fmt.Sprintf("for i in $(seq 1 %d); do %s http://%s:%d 2>&1 || true; echo; done", serviceIPPort := net.JoinHostPort(serviceIP, strconv.Itoa(servicePort))
50*len(expectedPods), wget, serviceIP, servicePort) return fmt.Sprintf("for i in $(seq 1 %d); do %s http://%s 2>&1 || true; echo; done",
50*len(expectedPods), wget, serviceIPPort)
} }
commands := []func() string{ commands := []func() string{
// verify service from node // verify service from node
...@@ -1360,8 +1363,12 @@ func VerifyServeHostnameServiceUp(c clientset.Interface, ns, host string, expect ...@@ -1360,8 +1363,12 @@ func VerifyServeHostnameServiceUp(c clientset.Interface, ns, host string, expect
} }
func VerifyServeHostnameServiceDown(c clientset.Interface, host string, serviceIP string, servicePort int) error { func VerifyServeHostnameServiceDown(c clientset.Interface, host string, serviceIP string, servicePort int) error {
ipPort := net.JoinHostPort(serviceIP, strconv.Itoa(servicePort))
// The current versions of curl included in CentOS and RHEL distros
// misinterpret square brackets around IPv6 as globbing, so use the -g
// argument to disable globbing to handle the IPv6 case.
command := fmt.Sprintf( command := fmt.Sprintf(
"curl -s --connect-timeout 2 http://%s:%d && exit 99", serviceIP, servicePort) "curl -g -s --connect-timeout 2 http://%s && exit 99", ipPort)
for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5 * time.Second) { for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5 * time.Second) {
result, err := SSH(command, host, TestContext.Provider) result, err := SSH(command, host, TestContext.Provider)
......
...@@ -4499,7 +4499,7 @@ func LaunchWebserverPod(f *Framework, podName, nodeName string) (ip string) { ...@@ -4499,7 +4499,7 @@ func LaunchWebserverPod(f *Framework, podName, nodeName string) (ip string) {
ExpectNoError(f.WaitForPodRunning(podName)) ExpectNoError(f.WaitForPodRunning(podName))
createdPod, err := podClient.Get(podName, metav1.GetOptions{}) createdPod, err := podClient.Get(podName, metav1.GetOptions{})
ExpectNoError(err) ExpectNoError(err)
ip = fmt.Sprintf("%s:%d", createdPod.Status.PodIP, port) ip = net.JoinHostPort(createdPod.Status.PodIP, strconv.Itoa(port))
Logf("Target pod IP:port is %s", ip) Logf("Target pod IP:port is %s", ip)
return return
} }
......
...@@ -20,6 +20,8 @@ import ( ...@@ -20,6 +20,8 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"math/rand" "math/rand"
"net"
"strconv"
"strings" "strings"
"time" "time"
...@@ -1632,7 +1634,9 @@ var _ = SIGDescribe("ESIPP [Slow] [DisabledForLargeClusters]", func() { ...@@ -1632,7 +1634,9 @@ var _ = SIGDescribe("ESIPP [Slow] [DisabledForLargeClusters]", func() {
// Confirm traffic can reach backend through LB before checking healthcheck nodeport. // Confirm traffic can reach backend through LB before checking healthcheck nodeport.
jig.TestReachableHTTP(ingressIP, svcTCPPort, framework.KubeProxyLagTimeout) jig.TestReachableHTTP(ingressIP, svcTCPPort, framework.KubeProxyLagTimeout)
expectedSuccess := nodes.Items[n].Name == endpointNodeName expectedSuccess := nodes.Items[n].Name == endpointNodeName
framework.Logf("Health checking %s, http://%s:%d%s, expectedSuccess %v", nodes.Items[n].Name, publicIP, healthCheckNodePort, path, expectedSuccess) port := strconv.Itoa(healthCheckNodePort)
ipPort := net.JoinHostPort(publicIP, port)
framework.Logf("Health checking %s, http://%s%s, expectedSuccess %v", nodes.Items[n].Name, ipPort, path, expectedSuccess)
Expect(jig.TestHTTPHealthCheckNodePort(publicIP, healthCheckNodePort, path, framework.KubeProxyEndpointLagTimeout, expectedSuccess, threshold)).NotTo(HaveOccurred()) Expect(jig.TestHTTPHealthCheckNodePort(publicIP, healthCheckNodePort, path, framework.KubeProxyEndpointLagTimeout, expectedSuccess, threshold)).NotTo(HaveOccurred())
} }
framework.ExpectNoError(framework.DeleteRCAndPods(f.ClientSet, f.InternalClientset, namespace, serviceName)) framework.ExpectNoError(framework.DeleteRCAndPods(f.ClientSet, f.InternalClientset, namespace, serviceName))
...@@ -1653,7 +1657,9 @@ var _ = SIGDescribe("ESIPP [Slow] [DisabledForLargeClusters]", func() { ...@@ -1653,7 +1657,9 @@ var _ = SIGDescribe("ESIPP [Slow] [DisabledForLargeClusters]", func() {
}() }()
ingressIP := framework.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0]) ingressIP := framework.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0])
path := fmt.Sprintf("%s:%d/clientip", ingressIP, int(svc.Spec.Ports[0].Port)) port := strconv.Itoa(int(svc.Spec.Ports[0].Port))
ipPort := net.JoinHostPort(ingressIP, port)
path := fmt.Sprintf("%s/clientip", ipPort)
nodeName := nodes.Items[0].Name nodeName := nodes.Items[0].Name
podName := "execpod-sourceip" podName := "execpod-sourceip"
...@@ -1804,9 +1810,10 @@ func execSourceipTest(f *framework.Framework, c clientset.Interface, ns, nodeNam ...@@ -1804,9 +1810,10 @@ func execSourceipTest(f *framework.Framework, c clientset.Interface, ns, nodeNam
framework.ExpectNoError(err) framework.ExpectNoError(err)
var stdout string var stdout string
serviceIPPort := net.JoinHostPort(serviceIP, strconv.Itoa(servicePort))
timeout := 2 * time.Minute timeout := 2 * time.Minute
framework.Logf("Waiting up to %v wget %s:%d", timeout, serviceIP, servicePort) framework.Logf("Waiting up to %v wget %s", timeout, serviceIPPort)
cmd := fmt.Sprintf(`wget -T 30 -qO- %s:%d | grep client_address`, serviceIP, servicePort) cmd := fmt.Sprintf(`wget -T 30 -qO- %s | grep client_address`, serviceIPPort)
for start := time.Now(); time.Since(start) < timeout; time.Sleep(2) { for start := time.Now(); time.Since(start) < timeout; time.Sleep(2) {
stdout, err = framework.RunHostCmd(execPod.Namespace, execPod.Name, cmd) stdout, err = framework.RunHostCmd(execPod.Namespace, execPod.Name, cmd)
if err != nil { if err != nil {
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
...@@ -278,7 +279,8 @@ func getWebserverEndpoints(client clientset.Interface) sets.String { ...@@ -278,7 +279,8 @@ func getWebserverEndpoints(client clientset.Interface) sets.String {
for _, ss := range endpoints.Subsets { for _, ss := range endpoints.Subsets {
for _, a := range ss.Addresses { for _, a := range ss.Addresses {
for _, p := range ss.Ports { for _, p := range ss.Ports {
eps.Insert(fmt.Sprintf("http://%s:%d", a.IP, p.Port)) ipPort := net.JoinHostPort(a.IP, fmt.Sprint(p.Port))
eps.Insert(fmt.Sprintf("http://%s", ipPort))
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment