github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/istio/authz/authpolicy_test.go (about)

     1  // Copyright (c) 2021, 2023, 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 authz
     5  
     6  import (
     7  	"fmt"
     8  	dump "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/clusterdump"
     9  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/update"
    10  	"net/http"
    11  	"time"
    12  
    13  	"github.com/verrazzano/verrazzano/pkg/k8s/resource"
    14  
    15  	. "github.com/onsi/ginkgo/v2"
    16  	. "github.com/onsi/gomega"
    17  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    18  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    19  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework"
    20  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework/metrics"
    21  	v1 "k8s.io/api/core/v1"
    22  	"k8s.io/apimachinery/pkg/api/errors"
    23  )
    24  
    25  const fooNamespace string = "foo"
    26  const barNamespace string = "bar"
    27  const noIstioNamespace string = "noistio"
    28  const labelPodName string = "app"
    29  const sleepWorkloadName = "sleep"
    30  const springFrontWorkloadName = "springboot-frontend"
    31  const springBackWorkloadName = "springboot-backend"
    32  
    33  var expectedPods = []string{"sleep-workload", "springboot-frontend-workload", "springboot-backend-workload"}
    34  var waitTimeout = 15 * time.Minute
    35  var pollingInterval = 30 * time.Second
    36  var shortPollingInterval = 10 * time.Second
    37  
    38  var t = framework.NewTestFramework("authz")
    39  
    40  var beforeSuite = t.BeforeSuiteFunc(func() {
    41  	start := time.Now()
    42  	deployFooApplication()
    43  	deployBarApplication()
    44  	deployNoIstioApplication()
    45  	metrics.Emit(t.Metrics.With("deployment_elapsed_time", time.Since(start).Milliseconds()))
    46  
    47  	//Resources for application bar
    48  	update.ValidatePods(sleepWorkloadName, labelPodName, barNamespace, 1, false)
    49  	update.ValidatePods(springFrontWorkloadName, labelPodName, barNamespace, 1, false)
    50  	update.ValidatePods(springBackWorkloadName, labelPodName, barNamespace, 1, false)
    51  
    52  	//Resources for application foo
    53  	update.ValidatePods(sleepWorkloadName, labelPodName, fooNamespace, 1, false)
    54  	update.ValidatePods(springFrontWorkloadName, labelPodName, fooNamespace, 1, false)
    55  	update.ValidatePods(springBackWorkloadName, labelPodName, fooNamespace, 1, false)
    56  
    57  	//Resources for application noIstio
    58  	update.ValidatePods(sleepWorkloadName, "app", noIstioNamespace, 1, false)
    59  	update.ValidatePods(springFrontWorkloadName, labelPodName, noIstioNamespace, 1, false)
    60  	update.ValidatePods(springBackWorkloadName, labelPodName, noIstioNamespace, 1, false)
    61  	beforeSuitePassed = true
    62  })
    63  
    64  var _ = BeforeSuite(beforeSuite)
    65  
    66  var failed = false
    67  var beforeSuitePassed = false
    68  
    69  var _ = t.AfterEach(func() {
    70  	failed = failed || framework.VzCurrentGinkgoTestDescription().Failed()
    71  })
    72  
    73  var afterSuite = t.AfterSuiteFunc(func() {
    74  	if failed || !beforeSuitePassed {
    75  		dump.ExecuteBugReport(fooNamespace, barNamespace, noIstioNamespace)
    76  	}
    77  	start := time.Now()
    78  	undeployFooApplication()
    79  	undeployBarApplication()
    80  	undeployNoIstioApplication()
    81  	metrics.Emit(t.Metrics.With("undeployment_elapsed_time", time.Since(start).Milliseconds()))
    82  })
    83  
    84  var _ = AfterSuite(afterSuite)
    85  
    86  func deployFooApplication() {
    87  	t.Logs.Info("Deploy Auth Policy Application in foo namespace")
    88  
    89  	t.Logs.Info("Create namespace")
    90  	Eventually(func() (*v1.Namespace, error) {
    91  		return pkg.CreateNamespace(fooNamespace, map[string]string{"verrazzano-managed": "true", "istio-injection": istioInjection})
    92  	}, waitTimeout, shortPollingInterval).ShouldNot(BeNil())
    93  
    94  	t.Logs.Info("Create AuthPolicy App resources")
    95  	Eventually(func() error {
    96  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/istio-securitytest-app.yaml")
    97  		if err != nil {
    98  			return err
    99  		}
   100  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   101  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   102  
   103  	t.Logs.Info("Create Sleep Component")
   104  	Eventually(func() error {
   105  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/sleep-comp.yaml")
   106  		if err != nil {
   107  			return err
   108  		}
   109  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   110  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   111  
   112  	t.Logs.Info("Create Backend Component")
   113  	Eventually(func() error {
   114  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/springboot-backend.yaml")
   115  		if err != nil {
   116  			return err
   117  		}
   118  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   119  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   120  
   121  	t.Logs.Info("Create Frontend Component")
   122  	Eventually(func() error {
   123  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/springboot-frontend.yaml")
   124  		if err != nil {
   125  			return err
   126  		}
   127  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   128  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   129  
   130  }
   131  
   132  func deployBarApplication() {
   133  	t.Logs.Info("Deploy Auth Policy Application in bar namespace")
   134  
   135  	t.Logs.Info("Create namespace")
   136  	Eventually(func() (*v1.Namespace, error) {
   137  		return pkg.CreateNamespace(barNamespace, map[string]string{"verrazzano-managed": "true", "istio-injection": istioInjection})
   138  	}, waitTimeout, shortPollingInterval).ShouldNot(BeNil())
   139  
   140  	t.Logs.Info("Create AuthPolicy App resources")
   141  	Eventually(func() error {
   142  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/istio-securitytest-app.yaml")
   143  		if err != nil {
   144  			return err
   145  		}
   146  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   147  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   148  
   149  	t.Logs.Info("Create Sleep Component")
   150  	Eventually(func() error {
   151  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/sleep-comp.yaml")
   152  		if err != nil {
   153  			return err
   154  		}
   155  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   156  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   157  
   158  	t.Logs.Info("Create Backend Component")
   159  	Eventually(func() error {
   160  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/springboot-backend.yaml")
   161  		if err != nil {
   162  			return err
   163  		}
   164  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   165  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   166  
   167  	t.Logs.Info("Create Frontend Component")
   168  	Eventually(func() error {
   169  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/springboot-frontend.yaml")
   170  		if err != nil {
   171  			return err
   172  		}
   173  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   174  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   175  
   176  }
   177  
   178  func deployNoIstioApplication() {
   179  	t.Logs.Info("Deploy Auth Policy Application in NoIstio namespace")
   180  
   181  	t.Logs.Info("Create namespace")
   182  	Eventually(func() (*v1.Namespace, error) {
   183  		return pkg.CreateNamespace(noIstioNamespace, map[string]string{"verrazzano-managed": "true"})
   184  	}, waitTimeout, shortPollingInterval).ShouldNot(BeNil())
   185  
   186  	t.Logs.Info("Create AuthPolicy App resources")
   187  	Eventually(func() error {
   188  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/istio-securitytest-app.yaml")
   189  		if err != nil {
   190  			return err
   191  		}
   192  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   193  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   194  
   195  	t.Logs.Info("Create Sleep Component")
   196  	Eventually(func() error {
   197  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/sleep-comp.yaml")
   198  		if err != nil {
   199  			return err
   200  		}
   201  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   202  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   203  
   204  	t.Logs.Info("Create Backend Component")
   205  	Eventually(func() error {
   206  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/springboot-backend.yaml")
   207  		if err != nil {
   208  			return err
   209  		}
   210  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   211  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   212  
   213  	t.Logs.Info("Create Frontend Component")
   214  	Eventually(func() error {
   215  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/springboot-frontend.yaml")
   216  		if err != nil {
   217  			return err
   218  		}
   219  		return resource.CreateOrUpdateResourceFromFile(file, t.Logs)
   220  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   221  
   222  }
   223  
   224  func undeployFooApplication() {
   225  	t.Logs.Info("Undeploy Auth Policy Application in foo namespace")
   226  
   227  	t.Logs.Info("Delete application")
   228  	Eventually(func() error {
   229  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/istio-securitytest-app.yaml")
   230  		if err != nil {
   231  			return err
   232  		}
   233  		return resource.DeleteResourceFromFile(file, t.Logs)
   234  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   235  
   236  	t.Logs.Info("Delete components")
   237  	Eventually(func() error {
   238  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/sleep-comp.yaml")
   239  		if err != nil {
   240  			return err
   241  		}
   242  		return resource.DeleteResourceFromFile(file, t.Logs)
   243  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   244  
   245  	Eventually(func() error {
   246  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/springboot-backend.yaml")
   247  		if err != nil {
   248  			return err
   249  		}
   250  		return resource.DeleteResourceFromFile(file, t.Logs)
   251  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   252  
   253  	Eventually(func() error {
   254  		file, err := pkg.FindTestDataFile("testdata/istio/authz/foo/springboot-frontend.yaml")
   255  		if err != nil {
   256  			return err
   257  		}
   258  		return resource.DeleteResourceFromFile(file, t.Logs)
   259  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   260  
   261  	Eventually(func() (bool, error) {
   262  		return pkg.PodsNotRunning(fooNamespace, expectedPods)
   263  	}, waitTimeout, shortPollingInterval).Should(BeTrue(), fmt.Sprintf("Pods in namespace %s stuck terminating!", fooNamespace))
   264  
   265  	t.Logs.Info("Delete namespace")
   266  	Eventually(func() error {
   267  		return pkg.DeleteNamespace(fooNamespace)
   268  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   269  
   270  	Eventually(func() bool {
   271  		_, err := pkg.GetNamespace(fooNamespace)
   272  		return err != nil && errors.IsNotFound(err)
   273  	}, waitTimeout, shortPollingInterval).Should(BeTrue())
   274  }
   275  
   276  func undeployBarApplication() {
   277  	t.Logs.Info("Undeploy Auth Policy Application in bar namespace")
   278  
   279  	t.Logs.Info("Delete application")
   280  	Eventually(func() error {
   281  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/istio-securitytest-app.yaml")
   282  		if err != nil {
   283  			return err
   284  		}
   285  		return resource.DeleteResourceFromFile(file, t.Logs)
   286  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   287  
   288  	t.Logs.Info("Delete components")
   289  	Eventually(func() error {
   290  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/sleep-comp.yaml")
   291  		if err != nil {
   292  			return err
   293  		}
   294  		return resource.DeleteResourceFromFile(file, t.Logs)
   295  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   296  
   297  	Eventually(func() error {
   298  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/springboot-backend.yaml")
   299  		if err != nil {
   300  			return err
   301  		}
   302  		return resource.DeleteResourceFromFile(file, t.Logs)
   303  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   304  
   305  	Eventually(func() error {
   306  		file, err := pkg.FindTestDataFile("testdata/istio/authz/bar/springboot-frontend.yaml")
   307  		if err != nil {
   308  			return err
   309  		}
   310  		return resource.DeleteResourceFromFile(file, t.Logs)
   311  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   312  
   313  	Eventually(func() (bool, error) {
   314  		return pkg.PodsNotRunning(barNamespace, expectedPods)
   315  	}, waitTimeout, shortPollingInterval).Should(BeTrue(), fmt.Sprintf("Pods in namespace %s stuck terminating!", barNamespace))
   316  
   317  	t.Logs.Info("Delete namespace")
   318  	Eventually(func() error {
   319  		return pkg.DeleteNamespace(barNamespace)
   320  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   321  
   322  	Eventually(func() bool {
   323  		_, err := pkg.GetNamespace(barNamespace)
   324  		return err != nil && errors.IsNotFound(err)
   325  	}, waitTimeout, shortPollingInterval).Should(BeTrue())
   326  }
   327  
   328  func undeployNoIstioApplication() {
   329  	t.Logs.Info("Undeploy Auth Policy Application in noistio namespace")
   330  
   331  	t.Logs.Info("Delete application")
   332  	Eventually(func() error {
   333  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/istio-securitytest-app.yaml")
   334  		if err != nil {
   335  			return err
   336  		}
   337  		return resource.DeleteResourceFromFile(file, t.Logs)
   338  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   339  
   340  	t.Logs.Info("Delete components")
   341  	Eventually(func() error {
   342  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/sleep-comp.yaml")
   343  		if err != nil {
   344  			return err
   345  		}
   346  		return resource.DeleteResourceFromFile(file, t.Logs)
   347  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   348  
   349  	Eventually(func() error {
   350  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/springboot-backend.yaml")
   351  		if err != nil {
   352  			return err
   353  		}
   354  		return resource.DeleteResourceFromFile(file, t.Logs)
   355  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   356  
   357  	Eventually(func() error {
   358  		file, err := pkg.FindTestDataFile("testdata/istio/authz/noistio/springboot-frontend.yaml")
   359  		if err != nil {
   360  			return err
   361  		}
   362  		return resource.DeleteResourceFromFile(file, t.Logs)
   363  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   364  
   365  	Eventually(func() (bool, error) {
   366  		return pkg.PodsNotRunning(noIstioNamespace, expectedPods)
   367  	}, waitTimeout, shortPollingInterval).Should(BeTrue(), fmt.Sprintf("Pods in namespace %s stuck terminating!", noIstioNamespace))
   368  
   369  	t.Logs.Info("Delete namespace")
   370  	Eventually(func() error {
   371  		return pkg.DeleteNamespace(noIstioNamespace)
   372  	}, waitTimeout, shortPollingInterval).ShouldNot(HaveOccurred())
   373  
   374  	Eventually(func() bool {
   375  		_, err := pkg.GetNamespace(noIstioNamespace)
   376  		return err != nil && errors.IsNotFound(err)
   377  	}, waitTimeout, shortPollingInterval).Should(BeTrue())
   378  }
   379  
   380  var _ = t.Describe("AuthPolicy test,", Label("f:security.authpol",
   381  	"f:app-lcm.spring-workload"), func() {
   382  	// Verify springboot-workload pod is running
   383  	// GIVEN springboot app is deployed
   384  	// WHEN the component and appconfig are created
   385  	// THEN the expected pod must be running in the test namespace
   386  	t.Context("check app deployment", func() {
   387  		t.It("in foo namespace", func() {
   388  			Eventually(func() bool {
   389  				return checkPodsRunning(fooNamespace, expectedPods)
   390  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", fooNamespace))
   391  		})
   392  	})
   393  
   394  	t.Context("check app deployment", func() {
   395  		t.It("in bar namespace", func() {
   396  			Eventually(func() bool {
   397  				return checkPodsRunning(barNamespace, expectedPods)
   398  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", barNamespace))
   399  		})
   400  	})
   401  
   402  	t.Context("check app deployment", func() {
   403  		t.It("in noistio namespace", func() {
   404  			Eventually(func() bool {
   405  				return checkPodsRunning(noIstioNamespace, expectedPods)
   406  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", noIstioNamespace))
   407  		})
   408  	})
   409  
   410  	var fooHost = ""
   411  	var barHost = ""
   412  	var noIstioHost = ""
   413  
   414  	var err error
   415  	t.BeforeEach(func() {
   416  		Eventually(func() (string, error) {
   417  			fooHost, err = k8sutil.GetHostnameFromGateway(fooNamespace, "")
   418  			return fooHost, err
   419  		}, waitTimeout, shortPollingInterval).Should(Not(BeEmpty()), fmt.Sprintf("Failed to get host from gateway in %s", fooNamespace))
   420  
   421  		Eventually(func() (string, error) {
   422  			barHost, err = k8sutil.GetHostnameFromGateway(barNamespace, "")
   423  			return barHost, err
   424  		}, waitTimeout, shortPollingInterval).Should(Not(BeEmpty()), fmt.Sprintf("Failed to get host from gateway in %s", barNamespace))
   425  
   426  		Eventually(func() (string, error) {
   427  			noIstioHost, err = k8sutil.GetHostnameFromGateway(noIstioNamespace, "")
   428  			return noIstioHost, err
   429  		}, waitTimeout, shortPollingInterval).Should(Not(BeEmpty()), fmt.Sprintf("Failed to get host from gateway in %s", noIstioNamespace))
   430  	})
   431  
   432  	// Verify application in namespace foo is working
   433  	// GIVEN authorization test app is deployed
   434  	// WHEN the component and appconfig with ingress trait are created
   435  	// THEN the application endpoint must be accessible
   436  	t.It("Verify welcome page of Foo Spring Boot FrontEnd is working.", func() {
   437  		Eventually(func() (*pkg.HTTPResponse, error) {
   438  			t.Logs.Infof("Ingress: %s", fooHost)
   439  			url := fmt.Sprintf("https://%s/", fooHost)
   440  			return pkg.GetWebPage(url, fooHost)
   441  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyContains("Greetings from Verrazzano Enterprise Container Platform")))
   442  	})
   443  
   444  	// Verify application in namespace bar is working
   445  	// GIVEN authorization test app is deployed
   446  	// WHEN the component and appconfig with ingress trait are created
   447  	// THEN the application endpoint must be accessible
   448  	t.It("Verify welcome page of Bar Spring Boot FrontEnd is working.", func() {
   449  		Eventually(func() (*pkg.HTTPResponse, error) {
   450  			t.Logs.Infof("Ingress: %s", barHost)
   451  			url := fmt.Sprintf("https://%s/", barHost)
   452  			return pkg.GetWebPage(url, barHost)
   453  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyContains("Greetings from Verrazzano Enterprise Container Platform")))
   454  	})
   455  
   456  	// Verify application in namespace bar is working
   457  	// GIVEN authorization test app is deployed
   458  	// WHEN the component and appconfig with ingress trait are created
   459  	// THEN the application endpoint must be accessible
   460  	t.It("Verify welcome page of NoIstio Spring Boot FrontEnd is working.", func() {
   461  		Eventually(func() (*pkg.HTTPResponse, error) {
   462  			t.Logs.Infof("Ingress: %s", noIstioHost)
   463  			url := fmt.Sprintf("https://%s/", noIstioHost)
   464  			return pkg.GetWebPage(url, noIstioHost)
   465  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyContains("Greetings from Verrazzano Enterprise Container Platform")))
   466  	})
   467  
   468  	// Verify Frontend can call Backend in foo
   469  	// GIVEN authorization test app is deployed
   470  	// WHEN the component and appconfig with ingress trait are created
   471  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   472  	// the http code is returned in the response body and captured in content
   473  	t.It("Verify Foo Frontend can call Foo Backend.", func() {
   474  		Eventually(func() (*pkg.HTTPResponse, error) {
   475  			t.Logs.Infof("Ingress: %s", fooHost)
   476  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.foo:8080/", fooHost)
   477  			return pkg.GetWebPage(url, fooHost)
   478  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyEquals("200")))
   479  	})
   480  
   481  	// Verify Frontend can call Backend in bar
   482  	// GIVEN authorization test app is deployed
   483  	// WHEN the component and appconfig with ingress trait are created
   484  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   485  	// the http code is returned in the response body and captured in content
   486  	t.It("Verify Bar Frontend can call Bar Backend.", func() {
   487  		Eventually(func() (*pkg.HTTPResponse, error) {
   488  			t.Logs.Infof("Ingress: %s", barHost)
   489  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.bar:8080/", barHost)
   490  			return pkg.GetWebPage(url, barHost)
   491  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyEquals("200")))
   492  	})
   493  
   494  	// Verify Foo Frontend can't call bar Backend
   495  	// GIVEN authorization test app is deployed
   496  	// WHEN the component and appconfig with ingress trait are created
   497  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   498  	// the http code is returned in the response body and captured in content
   499  	t.It("Verify Foo Frontend canNOT call Bar Backend.", func() {
   500  		Eventually(func() (*pkg.HTTPResponse, error) {
   501  			t.Logs.Infof("Ingress: %s", fooHost)
   502  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.bar:8080/", fooHost)
   503  			return pkg.GetWebPage(url, fooHost)
   504  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyEquals("403")))
   505  	})
   506  
   507  	// Verify Bar Frontend can't call Foo Backend
   508  	// GIVEN authorization test app is deployed
   509  	// WHEN the component and appconfig with ingress trait are created
   510  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   511  	// the http code is returned in the response body and captured in content
   512  	t.It("Verify Bar Frontend canNOT call Foo Backend.", func() {
   513  		Eventually(func() (*pkg.HTTPResponse, error) {
   514  			t.Logs.Infof("Ingress: %s", barHost)
   515  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.foo:8080/", barHost)
   516  			return pkg.GetWebPage(url, barHost)
   517  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyEquals("403")))
   518  	})
   519  
   520  	// Verify Bar Frontend can call NoIstio Backend
   521  	// GIVEN authorization test app is deployed
   522  	// WHEN the component and appconfig with ingress trait are created
   523  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   524  	// the http code is returned in the response body and captured in content
   525  	t.It("Verify Bar Frontend can call NoIstio Backend.", func() {
   526  		Eventually(func() (*pkg.HTTPResponse, error) {
   527  			t.Logs.Infof("Ingress: %s", barHost)
   528  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.noistio:8080/", barHost)
   529  			return pkg.GetWebPage(url, barHost)
   530  		}, waitTimeout, shortPollingInterval).Should(And(pkg.HasStatus(http.StatusOK), pkg.BodyEquals("200")))
   531  	})
   532  
   533  	// Verify noistio Frontend can't call bar Backend
   534  	// GIVEN authorization test app is deployed
   535  	// WHEN the component and appconfig with ingress trait are created
   536  	// THEN the frontend should be able to successfully call the backend and get a 200 on that invocation
   537  	// the http code is returned in the response body and captured in content
   538  	// *** This call should fail for a 500 because Non-Istio can't call Istio when MTLS is STRICT
   539  	// If this should fail because the call succeeded, verify that peerauthentication exists in istio-system and is set to STRICT
   540  	t.It("Verify NoIstio Frontend canNOT call Bar Backend.", func() {
   541  		kubeconfigPath, err := k8sutil.GetKubeConfigLocation()
   542  		Expect(err).ShouldNot(HaveOccurred())
   543  		Eventually(func() bool {
   544  			t.Logs.Infof("Ingress: %s", noIstioHost)
   545  			url := fmt.Sprintf("https://%s/externalCall?inurl=http://springboot-backend-workload.bar:8080/", noIstioHost)
   546  			client, err := pkg.GetVerrazzanoNoRetryHTTPClient(kubeconfigPath)
   547  			if err != nil {
   548  				t.Logs.Errorf("Failed to get client: %v", err)
   549  				return false
   550  			}
   551  			req, err := http.NewRequest("GET", url, nil)
   552  			if err != nil {
   553  				t.Logs.Errorf("Failed to create http request: %v", err)
   554  				return false
   555  			}
   556  			req.Host = noIstioHost
   557  
   558  			q := req.URL.Query()
   559  			q.Add("inurl", "https://springboot-backend-workload.bar:8080/")
   560  			req.URL.RawQuery = q.Encode()
   561  
   562  			resp, err := client.Do(req)
   563  			if err != nil {
   564  				// could be a transient network error so log it and let the Eventually retry
   565  				t.Logs.Errorf("Failed to do http request: %v", err)
   566  				return false
   567  			}
   568  			return resp.StatusCode == 500
   569  		}, waitTimeout, shortPollingInterval).Should(BeTrue(), "Failed to Verify NoIstio Frontend canNOT call Bar Backend")
   570  	})
   571  
   572  })
   573  
   574  var _ = t.Describe("Verify Auth Policy Prometheus Scrape Targets", func() {
   575  	// Verify springboot-workload pod is running
   576  	// GIVEN springboot app is deployed
   577  	// WHEN the component and appconfig are created
   578  	// THEN the expected pod must be running in the test namespace
   579  	t.Context("Deployment.", func() {
   580  		t.It("and waiting for expected pods must be running", func() {
   581  			Eventually(func() bool {
   582  				return checkPodsRunning(fooNamespace, expectedPods)
   583  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", fooNamespace))
   584  		})
   585  	})
   586  
   587  	t.Context("Deployment.", func() {
   588  		t.It("and waiting for expected pods must be running", func() {
   589  			Eventually(func() bool {
   590  				return checkPodsRunning(barNamespace, expectedPods)
   591  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", barNamespace))
   592  		})
   593  	})
   594  
   595  	t.Context("Deployment.", func() {
   596  		t.It("and waiting for expected pods must be running", func() {
   597  			Eventually(func() bool {
   598  				return checkPodsRunning(noIstioNamespace, expectedPods)
   599  			}, waitTimeout, pollingInterval).Should(BeTrue(), fmt.Sprintf("Auth Policy Application failed to start in %s", noIstioNamespace))
   600  		})
   601  	})
   602  
   603  	// Verify That Generated Prometheus Scrape Targets for authpolicy-appconf_foo_springboot-frontend is using https for scraping
   604  	// GIVEN that springboot deployed to Istio namespace foo
   605  	// WHEN the Prometheus ServiceMonitors are created
   606  	// THEN they should be created to use the https protocol
   607  	t.It("Verify that ServiceMonitor authpolicy-appconf-foo-springboot-frontend is using https for scraping.", func() {
   608  		Eventually(func() bool {
   609  			serviceMonitor, err := pkg.GetServiceMonitor(fooNamespace, "authpolicy-appconf-foo-springboot-frontend")
   610  			if err != nil {
   611  				return false
   612  			}
   613  			return serviceMonitor.Spec.Endpoints[0].Scheme == "https"
   614  		}, waitTimeout, shortPollingInterval).Should(BeTrue(), "Failed to Verify that ServiceMonitor authpolicy-appconf-foo-springboot-frontend is using https for scraping")
   615  	})
   616  
   617  	// Verify That Generated Prometheus Scrape Targets for authpolicy-appconf_bar_springboot-frontend is using https for scraping
   618  	// GIVEN that springboot deployed to Istio namespace bar
   619  	// WHEN the Prometheus ServiceMonitors are created
   620  	// THEN they should be created to use the https protocol
   621  	t.It("Verify that ServiceMonitor authpolicy-appconf-bar-springboot-frontend is using https for scraping.", func() {
   622  		Eventually(func() bool {
   623  			serviceMonitor, err := pkg.GetServiceMonitor(barNamespace, "authpolicy-appconf-bar-springboot-frontend")
   624  			if err != nil {
   625  				return false
   626  			}
   627  			return serviceMonitor.Spec.Endpoints[0].Scheme == "https"
   628  		}, waitTimeout, shortPollingInterval).Should(BeTrue(), "Failed to Verify that ServiceMonitor authpolicy-appconf-bar-springboot-frontend is using https for scraping")
   629  	})
   630  
   631  	// Verify That Generated Prometheus Scrape Targets for authpolicy-appconf_noistio_springboot-frontend is using http for scraping
   632  	// GIVEN that springboot deployed to namespace noistio
   633  	// WHEN the Prometheus ServiceMonitors are created
   634  	// THEN they should be created to use the http protocol
   635  	t.It("Verify that ServiceMonitor authpolicy-appconf-noistio-springboot-frontend is using http for scraping.", func() {
   636  		Eventually(func() bool {
   637  			serviceMonitor, err := pkg.GetServiceMonitor(noIstioNamespace, "authpolicy-appconf-noistio-springboot-frontend")
   638  			if err != nil {
   639  				return false
   640  			}
   641  			return serviceMonitor.Spec.Endpoints[0].Scheme == "http"
   642  		}, waitTimeout, shortPollingInterval).Should(BeTrue(), "Failed to Verify that ServiceMonitor authpolicy-appconf-noistio-springboot-frontend is using http for scraping")
   643  	})
   644  
   645  })
   646  
   647  // checkPodsRunning checks whether the pods are ready in a given namespace
   648  func checkPodsRunning(namespace string, expectedPods []string) bool {
   649  	result, err := pkg.PodsRunning(namespace, expectedPods)
   650  	if err != nil {
   651  		AbortSuite(fmt.Sprintf("One or more pods are not running in the namespace: %v, error: %v", namespace, err))
   652  	}
   653  	return result
   654  }