diff --git a/test/extended/router/h2spec.go b/test/extended/router/h2spec.go index d8af2b42654d..f7edf4abb641 100644 --- a/test/extended/router/h2spec.go +++ b/test/extended/router/h2spec.go @@ -24,6 +24,7 @@ import ( admissionapi "k8s.io/pod-security-admission/api" utilpointer "k8s.io/utils/pointer" + configv1 "github.com/openshift/api/config/v1" routev1 "github.com/openshift/api/route/v1" securityv1 "github.com/openshift/api/security/v1" routeclientset "github.com/openshift/client-go/route/clientset/versioned" @@ -71,6 +72,14 @@ var _ = g.Describe("[sig-network-edge][Conformance][Area:Networking][Feature:Rou g.Skip("Skip on platforms where the default router is not exposed by a load balancer service.") } + dualStackIPFamily := false + if infra.Status.PlatformStatus != nil && infra.Status.PlatformStatus.AWS != nil { + ipFamily := infra.Status.PlatformStatus.AWS.IPFamily + if ipFamily == configv1.DualStackIPv4Primary || ipFamily == configv1.DualStackIPv6Primary { + dualStackIPFamily = true + } + } + g.By("Getting the default domain") defaultDomain, err := getDefaultIngressClusterDomainName(oc, time.Minute) o.Expect(err).NotTo(o.HaveOccurred(), "failed to find default domain name") @@ -96,6 +105,13 @@ var _ = g.Describe("[sig-network-edge][Conformance][Area:Networking][Feature:Rou ) o.Expect(err).NotTo(o.HaveOccurred()) + // On dual-stack clusters, HAProxy needs a separate IPv6 bind + // with v6only to listen on both address families. + v6onlyBind := "" + if dualStackIPFamily { + v6onlyBind = "\n\tbind :::8443 ssl crt /tmp/bundle.pem alpn h2 v6only" + } + g.By("Creating h2spec test service config") ns := oc.KubeFramework().Namespace.Name configMap := &corev1.ConfigMap{ @@ -127,7 +143,7 @@ frontend fe_proxy_tls declare capture request len 40000 http-request capture req.body id 0 log global - bind *:8443 ssl crt /tmp/bundle.pem alpn h2 + bind *:8443 ssl crt /tmp/bundle.pem alpn h2` + v6onlyBind + ` default_backend haproxy-availability-ok backend haproxy-availability-ok errorfile 503 /etc/haproxy/errorfile diff --git a/test/extended/router/headers.go b/test/extended/router/headers.go index e6c73ffc7a45..aaf255de495c 100644 --- a/test/extended/router/headers.go +++ b/test/extended/router/headers.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "os" "strings" "time" @@ -54,8 +55,12 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:operator.openshift.io o.Expect(network).NotTo(o.BeNil()) platformType := infra.Status.Platform + dualStackIPv6Primary := false if infra.Status.PlatformStatus != nil { platformType = infra.Status.PlatformStatus.Type + if infra.Status.PlatformStatus.AWS != nil { + dualStackIPv6Primary = infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv6Primary + } } switch platformType { case configv1.AWSPlatformType, configv1.AzurePlatformType, configv1.GCPPlatformType: @@ -79,7 +84,15 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:operator.openshift.io g.By(fmt.Sprintf("creating an http echo server from a config file %q", configPath)) - err := oc.Run("create").Args("-f", configPath).Execute() + configData, err := os.ReadFile(configPath) + o.Expect(err).NotTo(o.HaveOccurred()) + config := string(configData) + // On IPv6-primary clusters, socat must listen on IPv6. + if dualStackIPv6Primary { + g.By("with IPv6 listen") + config = strings.ReplaceAll(config, "TCP4-LISTEN", "TCP6-LISTEN") + } + err = oc.Run("create").Args("-f", "-").InputString(config).Execute() o.Expect(err).NotTo(o.HaveOccurred()) var clientIP string diff --git a/test/extended/router/idle.go b/test/extended/router/idle.go index 7669075d9e7f..e89a402d10b6 100644 --- a/test/extended/router/idle.go +++ b/test/extended/router/idle.go @@ -64,6 +64,14 @@ var _ = g.Describe("[sig-network-edge][Conformance][Area:Networking][Feature:Rou g.Skip("https://bugzilla.redhat.com/show_bug.cgi?id=1933114") } + // On IPv6-primary clusters, socat must listen on IPv6 since + // the readiness probe connects via the pod's IPv6 address. + socatListen := "TCP4-LISTEN:8080" + if infra.Status.PlatformStatus.AWS != nil && + infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv6Primary { + socatListen = "TCP6-LISTEN:8080" + } + timeout := 15 * time.Minute g.By("creating test fixtures") @@ -149,7 +157,7 @@ var _ = g.Describe("[sig-network-edge][Conformance][Area:Networking][Feature:Rou }, Command: []string{ "/usr/bin/socat", - "TCP4-LISTEN:8080,reuseaddr,fork", + socatListen + ",reuseaddr,fork", `EXEC:'/bin/bash -c \"printf \\\"HTTP/1.0 200 OK\r\n\r\n\\\"; sed -e \\\"/^\r/q\\\"\"'`, }, Ports: []corev1.ContainerPort{ diff --git a/test/extended/router/metrics.go b/test/extended/router/metrics.go index b25732bbd64f..2aeb9c66102a 100644 --- a/test/extended/router/metrics.go +++ b/test/extended/router/metrics.go @@ -52,10 +52,19 @@ var _ = g.Describe("[sig-network][Feature:Router]", func() { infra, err := oc.AdminConfigClient().ConfigV1().Infrastructures().Get(context.Background(), "cluster", metav1.GetOptions{}) o.Expect(err).NotTo(o.HaveOccurred()) platformType := infra.Status.Platform + dualStackIPFamily := false if infra.Status.PlatformStatus != nil { platformType = infra.Status.PlatformStatus.Type + if infra.Status.PlatformStatus.AWS != nil { + ipFamily := infra.Status.PlatformStatus.AWS.IPFamily + if ipFamily == configv1.DualStackIPv4Primary || ipFamily == configv1.DualStackIPv6Primary { + dualStackIPFamily = true + } + } } - proxyProtocol = platformType == configv1.AWSPlatformType + // Dual-stack installations on AWS are forced to use NLB type, which + // doesn't accept proxy protocol (yet). + proxyProtocol = (platformType == configv1.AWSPlatformType) && !dualStackIPFamily // This test needs to make assertions against a single router pod, so all access // to the router should happen through a single endpoint.