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 }