github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/verify-install/web/nginx_errors_test.go (about)

     1  // Copyright (c) 2022, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package web_test
     5  
     6  import (
     7  	"context"
     8  	"crypto/tls"
     9  	"fmt"
    10  	"net/http"
    11  	"os"
    12  	"strings"
    13  
    14  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    15  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    16  
    17  	"github.com/hashicorp/go-retryablehttp"
    18  	. "github.com/onsi/ginkgo/v2"
    19  	. "github.com/onsi/gomega"
    20  )
    21  
    22  const (
    23  	minimumVersion = "1.3.0"
    24  	expected400    = "<html>\n<head><title>400 Bad Request</title></head>\n<body>\n<center><h1>400 Bad Request</h1></center>\n</body>\n</html>"
    25  	expected404    = "<html>\n<head><title>404 Not Found</title></head>\n<body>\n<center><h1>404 Not Found</h1></center>\n</body>\n</html>"
    26  )
    27  
    28  var _ = t.Describe("nginx error pages", Label("f:mesh.ingress", "f:mesh.traffic-mgmt"), func() {
    29  	t.Context("test that an", func() {
    30  		kubeconfigPath, err := k8sutil.GetKubeConfigLocation()
    31  		if err != nil {
    32  			Fail(fmt.Sprintf("Failed to get default kubeconfig path: %s", err.Error()))
    33  		}
    34  		t.ItMinimumVersion("Incorrect path returns a 404", minimumVersion, kubeconfigPath, func() {
    35  			if !pkg.IsManagedClusterProfile() {
    36  				Eventually(func() (string, error) {
    37  					kubeConfigPath, err := k8sutil.GetKubeConfigLocation()
    38  					if err != nil {
    39  						t.Logs.Errorf("Error getting kubeconfig: %v", err)
    40  						return "", err
    41  					}
    42  					api := pkg.EventuallyGetAPIEndpoint(kubeConfigPath)
    43  					esURL, err := api.GetOpensearchURL()
    44  					if err != nil {
    45  						t.Logs.Errorf("Error getting Elasticsearch URL: %v", err)
    46  						return "", err
    47  					}
    48  					req, err := retryablehttp.NewRequest("GET", esURL+"/invalid-url", nil)
    49  					if err != nil {
    50  						t.Logs.Errorf("Error creating Request: %v", err)
    51  						return "", err
    52  					}
    53  					password, err := pkg.GetVerrazzanoPasswordInCluster(kubeConfigPath)
    54  					if err != nil {
    55  						t.Logs.Errorf("Error getting Verrazzano Password: %v", err)
    56  						return "", err
    57  					}
    58  					req.SetBasicAuth(pkg.Username, password)
    59  					return checkNGINXErrorPage(req, 404)
    60  				}, waitTimeout, pollingInterval).Should(Not(ContainSubstring("nginx")),
    61  					"Expected response to not leak the name nginx")
    62  			}
    63  		})
    64  
    65  		t.ItMinimumVersion("Incorrect password returns a 401", minimumVersion, kubeconfigPath, func() {
    66  			if !pkg.IsManagedClusterProfile() {
    67  				Eventually(func() (string, error) {
    68  					kubeConfigPath, err := k8sutil.GetKubeConfigLocation()
    69  					if err != nil {
    70  						t.Logs.Errorf("Error getting kubeconfig: %v", err)
    71  						return "", err
    72  					}
    73  					api := pkg.EventuallyGetAPIEndpoint(kubeConfigPath)
    74  					esURL, err := api.GetOpensearchURL()
    75  					if err != nil {
    76  						t.Logs.Errorf("Error getting Elasticsearch URL: %v", err)
    77  						return "", err
    78  					}
    79  					req, err := retryablehttp.NewRequest("GET", esURL, nil)
    80  					if err != nil {
    81  						t.Logs.Errorf("Error creating Request: %v", err)
    82  						return "", err
    83  					}
    84  					req.SetBasicAuth(pkg.Username, "fake-password")
    85  					return checkNGINXErrorPage(req, 401)
    86  				}, waitTimeout, pollingInterval).Should(Not(ContainSubstring("nginx")),
    87  					"Expected response to not leak the name nginx")
    88  			}
    89  		})
    90  
    91  		t.ItMinimumVersion("Incorrect host returns a 404", minimumVersion, kubeconfigPath, func() {
    92  			if !pkg.IsManagedClusterProfile() && os.Getenv("TEST_ENV") != "ocidns_oke" && os.Getenv("TEST_ENV") != "OCNE" && os.Getenv("TEST_ENV") != "LRE" && os.Getenv("TEST_ENV") != "kind_oci_dns" {
    93  				Eventually(func() (string, error) {
    94  					kubeConfigPath, err := k8sutil.GetKubeConfigLocation()
    95  					if err != nil {
    96  						t.Logs.Errorf("Error getting kubeconfig: %v", err)
    97  						return "", err
    98  					}
    99  					api := pkg.EventuallyGetAPIEndpoint(kubeConfigPath)
   100  					vzURL, err := api.GetVerrazzanoIngressURL()
   101  					if err != nil {
   102  						t.Logs.Errorf("Error getting Verrazzano Ingress URL: %v", err)
   103  						return "", err
   104  					}
   105  					badHost := strings.Replace(vzURL, "verrazzano", "badhost", 1)
   106  					req, err := retryablehttp.NewRequest("GET", badHost, nil)
   107  					if err != nil {
   108  						t.Logs.Errorf("Error creating Request: %v", err)
   109  						return "", err
   110  					}
   111  					password, err := pkg.GetVerrazzanoPasswordInCluster(kubeConfigPath)
   112  					if err != nil {
   113  						t.Logs.Errorf("Error getting Verrazzano Password: %v", err)
   114  						return "", err
   115  					}
   116  					req.SetBasicAuth(pkg.Username, password)
   117  					return checkNGINXErrorPage(req, 404)
   118  				}, waitTimeout, pollingInterval).Should(Equal(strings.TrimSpace(expected404)),
   119  					"Expected response to include custom 404 error page")
   120  			}
   121  		})
   122  
   123  		t.ItMinimumVersion("Directory traversal returns a 400", minimumVersion, kubeconfigPath, func() {
   124  			if !pkg.IsManagedClusterProfile() && os.Getenv("TEST_ENV") != "ocidns_oke" && os.Getenv("TEST_ENV") != "OCNE" && os.Getenv("TEST_ENV") != "LRE" && os.Getenv("TEST_ENV") != "kind_oci_dns" {
   125  				Eventually(func() (string, error) {
   126  					api := pkg.EventuallyGetAPIEndpoint(kubeconfigPath)
   127  					vzURL, err := api.GetVerrazzanoIngressURL()
   128  					if err != nil {
   129  						pkg.Log(pkg.Error, fmt.Sprintf("Error getting Verrazzano Ingress URL: %v", err))
   130  						return "", err
   131  					}
   132  					clusterIP := strings.Replace(vzURL, "verrazzano.", "", 1)
   133  					req, err := retryablehttp.NewRequest("GET", clusterIP+"/../../", nil)
   134  					if err != nil {
   135  						pkg.Log(pkg.Error, fmt.Sprintf("Error creating Request: %v", err))
   136  						return "", err
   137  					}
   138  					return checkNGINXErrorPage(req, 400)
   139  				}, waitTimeout, pollingInterval).Should(Equal(strings.TrimSpace(expected400)),
   140  					"Expected response to be the custom 400 error page")
   141  			}
   142  		})
   143  	})
   144  })
   145  
   146  func checkNGINXErrorPage(req *retryablehttp.Request, expectedStatus int) (string, error) {
   147  	transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec //#gosec G402
   148  	c := pkg.EventuallyVerrazzanoRetryableHTTPClient()
   149  	c.HTTPClient.Transport = transport
   150  	c.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) {
   151  		if resp == nil {
   152  			if err != nil {
   153  				t.Logs.Errorf("Request returned a nil response, error: %v", err)
   154  			}
   155  			return true, err
   156  		}
   157  		if resp.StatusCode == expectedStatus {
   158  			return false, nil
   159  		}
   160  		t.Logs.Infof("Request returned response code: %d, error: %v", resp.StatusCode, err)
   161  		return true, err
   162  	}
   163  	response, err := c.Do(req)
   164  	if err != nil {
   165  		t.Logs.Errorf("Error getting response: %v", err)
   166  		return "", err
   167  	}
   168  	httpResp, err := pkg.ProcessHTTPResponse(response)
   169  	if err != nil {
   170  		t.Logs.Errorf("Error reading response: %v", err)
   171  		return "", err
   172  	}
   173  	responseString := strings.TrimSpace(string(httpResp.Body))
   174  	t.Logs.Infof("Error page response: %s", responseString)
   175  	return responseString, err
   176  }