Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions test/e2e/gateway_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,10 @@ func testGatewayAPIRBAC(t *testing.T) {
}

func testGatewayAPIDNS(t *testing.T) {
if !isDNSManagementSupported(t) {
t.Skip("this test can be executed just on platforms that support managed DNS")
}

domain := "gws." + dnsConfig.Spec.BaseDomain

gatewayClass, err := createGatewayClass(operatorcontroller.OpenShiftDefaultGatewayClassName, operatorcontroller.OpenShiftGatewayClassControllerName)
Expand Down Expand Up @@ -591,6 +595,10 @@ func testGatewayAPIDNS(t *testing.T) {
}

func testGatewayAPIDNSListenerUpdate(t *testing.T) {
if !isDNSManagementSupported(t) {
t.Skip("this test can be executed just on platforms that support managed DNS")
}

gatewayClass, err := createGatewayClass(operatorcontroller.OpenShiftDefaultGatewayClassName, operatorcontroller.OpenShiftGatewayClassControllerName)
if err != nil {
t.Fatalf("failed to create gatewayclass: %v", err)
Expand Down
82 changes: 56 additions & 26 deletions test/e2e/util_gatewayapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"io"
"net"
"net/http"
"slices"
Expand Down Expand Up @@ -879,14 +879,6 @@ func assertHttpRouteSuccessful(t *testing.T, namespace, name string, gateway *ga
func assertHttpRouteConnection(t *testing.T, hostname string, gateway *gatewayapiv1.Gateway) error {
domain := ""

// Create the http client to check the header.
client := &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}

// Get gateway listener hostname to use for dnsRecord.
if len(gateway.Spec.Listeners) > 0 {
if gateway.Spec.Listeners[0].Hostname != nil && len(string(*gateway.Spec.Listeners[0].Hostname)) > 0 {
Expand All @@ -896,30 +888,68 @@ func assertHttpRouteConnection(t *testing.T, hostname string, gateway *gatewayap
}
}
}
// Obtain the standard formatting of the dnsRecord.
dnsRecordName := operatorcontroller.GatewayDNSRecordName(gateway, domain)

t.Logf("Making sure DNSRecord %v for domain %q is ready to use...", dnsRecordName, domain)
if err := assertDNSRecord(t, dnsRecordName); err != nil {
return err
managedDns := isDNSManagementSupported(t)

// On-prem platforms the DNS may not be managed, so we cannot check if it is available
if managedDns {
// Obtain the standard formatting of the dnsRecord.
dnsRecordName := operatorcontroller.GatewayDNSRecordName(gateway, domain)
t.Logf("Making sure DNSRecord %v for domain %q is ready to use...", dnsRecordName, domain)
if err := assertDNSRecord(t, dnsRecordName); err != nil {
return err
}

// Wait and check that the dns name resolves first. Takes a long time, so
// if the hostname is actually an IP address, skip this.
if net.ParseIP(hostname) == nil {
t.Logf("Attempting to resolve %s...", hostname)
if err := wait.PollUntilContextTimeout(context.Background(), 10*time.Second, dnsResolutionTimeout, false, func(context context.Context) (bool, error) {
_, err := net.LookupHost(hostname)
if err != nil {
t.Logf("%v waiting for HTTP route name %s to resolve (%v)", time.Now(), hostname, err)
return false, nil
}
return true, nil
}); err != nil {
t.Fatalf("Failed to resolve host name %s: %v", hostname, err)
}
}
}

transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}

// Wait and check that the dns name resolves first. Takes a long time, so
// if the hostname is actually an IP address, skip this.
if net.ParseIP(hostname) == nil {
t.Logf("Attempting to resolve %s...", hostname)
if err := wait.PollUntilContextTimeout(context.Background(), 10*time.Second, dnsResolutionTimeout, false, func(context context.Context) (bool, error) {
_, err := net.LookupHost(hostname)
if !managedDns {
if len(gateway.Status.Addresses) == 0 ||
gateway.Status.Addresses[0].Type == nil ||
*gateway.Status.Addresses[0].Type != gatewayapiv1.IPAddressType ||
gateway.Status.Addresses[0].Value == "" {
t.Fatalf("gateway test without managed DNS needs at least one address status set, got %v", gateway.Status.Addresses)
}

targetIP := gateway.Status.Addresses[0].Value
dialer := &net.Dialer{
Timeout: 15 * time.Second,
}
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
_, port, err := net.SplitHostPort(addr)
if err != nil {
t.Logf("%v waiting for HTTP route name %s to resolve (%v)", time.Now(), hostname, err)
return false, nil
return nil, err
}
return true, nil
}); err != nil {
t.Fatalf("Failed to resolve host name %s: %v", hostname, err)

destination := net.JoinHostPort(targetIP, port)
return dialer.DialContext(ctx, network, destination)
}
}

// Create the http client to check the header.
client := &http.Client{
Timeout: 10 * time.Second,
Transport: transport,
}

var (
statusCode int
body string
Expand Down Expand Up @@ -960,7 +990,7 @@ func getHTTPResponse(client *http.Client, name string) (int, http.Header, string

// Close response body.
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
body, err := io.ReadAll(response.Body)
if err != nil {
return 0, nil, "", fmt.Errorf("failed to read response body: %w", err)
}
Expand Down
33 changes: 33 additions & 0 deletions test/e2e/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,39 @@ func updateAndVerifyInfrastructureConfigWithRetry(t *testing.T, name types.Names
})
}

func isDNSManagementSupported(t *testing.T) bool {
t.Helper()
dnsConfig := &configv1.DNS{}
dnsManaged := false
name := types.NamespacedName{
Name: "cluster",
}
err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, timeout, false, func(ctx context.Context) (done bool, err error) {
if err := kclient.Get(ctx, name, dnsConfig); err != nil {
t.Logf("error getting dns config %v: %v, retrying...", name, err)
return false, nil
}

// On the majority of platforms, the *Zone not being null is enough
// On Azure, a platform can be null and be empty so we need to validate (this means unmanaged as well)
// On AWS, spec.ID is optional as AWS may use tags

managedPrivateZone := dnsConfig.Spec.PrivateZone != nil &&
(dnsConfig.Spec.PrivateZone.ID != "" || len(dnsConfig.Spec.PrivateZone.Tags) > 0)

managedPublicZone := dnsConfig.Spec.PublicZone != nil &&
(dnsConfig.Spec.PublicZone.ID != "" || len(dnsConfig.Spec.PublicZone.Tags) > 0)

dnsManaged = managedPrivateZone || managedPublicZone

return true, nil
})
if err != nil {
t.Fatalf("failed to define if Managed DNS is supported: %s", err)
}
return dnsManaged
}

// waitForCCMAvailableAndUpdated waits for Cloud Controller Manager Deployment
// to be reported as ready.
// If oldConfigurationHash is not empty it will additionally verify that the configuration hash
Expand Down