github.com/redhat-appstudio/release-service@v0.0.0-20240507045911-a8558ef3422a/controllers/release/adapter_test.go (about) 1 /* 2 Copyright 2022. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package release 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "os" 23 "reflect" 24 "strings" 25 "time" 26 "unicode" 27 28 tektonutils "github.com/redhat-appstudio/release-service/tekton/utils" 29 30 "github.com/konflux-ci/operator-toolkit/controller" 31 toolkit "github.com/konflux-ci/operator-toolkit/loader" 32 . "github.com/onsi/ginkgo/v2" 33 . "github.com/onsi/gomega" 34 "github.com/operator-framework/operator-lib/handler" 35 "github.com/redhat-appstudio/release-service/api/v1alpha1" 36 "github.com/redhat-appstudio/release-service/loader" 37 "github.com/redhat-appstudio/release-service/metadata" 38 tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" 39 corev1 "k8s.io/api/core/v1" 40 rbac "k8s.io/api/rbac/v1" 41 "k8s.io/apimachinery/pkg/runtime/schema" 42 "k8s.io/apimachinery/pkg/types" 43 44 ecapiv1alpha1 "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1" 45 applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" 46 47 "k8s.io/apimachinery/pkg/api/errors" 48 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 49 ctrl "sigs.k8s.io/controller-runtime" 50 ) 51 52 var _ = Describe("Release adapter", Ordered, func() { 53 var ( 54 createReleaseAndAdapter func() *adapter 55 createResources func() 56 deleteResources func() 57 58 application *applicationapiv1alpha1.Application 59 component *applicationapiv1alpha1.Component 60 enterpriseContractConfigMap *corev1.ConfigMap 61 enterpriseContractPolicy *ecapiv1alpha1.EnterpriseContractPolicy 62 releasePlan *v1alpha1.ReleasePlan 63 releasePlanAdmission *v1alpha1.ReleasePlanAdmission 64 releaseServiceConfig *v1alpha1.ReleaseServiceConfig 65 roleBinding *rbac.RoleBinding 66 snapshot *applicationapiv1alpha1.Snapshot 67 ) 68 69 AfterAll(func() { 70 deleteResources() 71 }) 72 73 BeforeAll(func() { 74 Expect(os.Setenv("DEFAULT_RELEASE_WORKSPACE_NAME", "release-workspace")).To(Succeed()) 75 Expect(os.Setenv("DEFAULT_RELEASE_WORKSPACE_SIZE", "1Gi")).To(Succeed()) 76 77 createResources() 78 }) 79 80 When("newAdapter is called", func() { 81 It("creates and return a new adapter", func() { 82 Expect(reflect.TypeOf(newAdapter(ctx, k8sClient, nil, loader.NewLoader(), &ctrl.Log))).To(Equal(reflect.TypeOf(&adapter{}))) 83 }) 84 }) 85 86 Context("When calling EnsureConfigIsLoaded", func() { 87 var adapter *adapter 88 89 AfterEach(func() { 90 _ = adapter.client.Delete(ctx, adapter.release) 91 }) 92 93 BeforeEach(func() { 94 adapter = createReleaseAndAdapter() 95 }) 96 97 It("returns an error if SERVICE_NAMESPACE is not set", func() { 98 adapter.release.MarkReleasing("") 99 result, err := adapter.EnsureConfigIsLoaded() 100 Expect(!result.RequeueRequest && result.CancelRequest).To(BeTrue()) 101 Expect(err).NotTo(HaveOccurred()) 102 Expect(adapter.release.IsValid()).To(BeFalse()) 103 Expect(adapter.release.HasReleaseFinished()).To(BeTrue()) 104 Expect(adapter.releaseServiceConfig).To(BeNil()) 105 }) 106 107 It("loads the ReleaseServiceConfig and assigns it to the adapter", func() { 108 os.Setenv("SERVICE_NAMESPACE", "default") 109 result, err := adapter.EnsureConfigIsLoaded() 110 Expect(!result.CancelRequest && !result.RequeueRequest).To(BeTrue()) 111 Expect(err).To(BeNil()) 112 Expect(adapter.releaseServiceConfig).NotTo(BeNil()) 113 Expect(adapter.releaseServiceConfig.Namespace).To(Equal("default")) 114 }) 115 116 It("creates and assigns an empty ReleaseServiceConfig if none is found", func() { 117 os.Setenv("SERVICE_NAMESPACE", "test") 118 result, err := adapter.EnsureConfigIsLoaded() 119 Expect(!result.CancelRequest && !result.RequeueRequest).To(BeTrue()) 120 Expect(err).To(BeNil()) 121 Expect(adapter.releaseServiceConfig).NotTo(BeNil()) 122 Expect(adapter.releaseServiceConfig.Namespace).To(Equal("test")) 123 }) 124 }) 125 126 When("EnsureFinalizersAreCalled is called", func() { 127 var adapter *adapter 128 129 AfterEach(func() { 130 _ = adapter.client.Delete(ctx, adapter.release) 131 }) 132 133 BeforeEach(func() { 134 adapter = createReleaseAndAdapter() 135 adapter.releaseServiceConfig = releaseServiceConfig 136 }) 137 138 It("should do nothing if the Release is not set to be deleted", func() { 139 result, err := adapter.EnsureFinalizersAreCalled() 140 Expect(err).NotTo(HaveOccurred()) 141 Expect(!result.CancelRequest && !result.RequeueRequest).To(BeTrue()) 142 }) 143 144 It("should finalize the Release if it's set to be deleted and it has a finalizer", func() { 145 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 146 { 147 ContextKey: loader.ProcessingResourcesContextKey, 148 Resource: &loader.ProcessingResources{ 149 EnterpriseContractConfigMap: enterpriseContractConfigMap, 150 EnterpriseContractPolicy: enterpriseContractPolicy, 151 ReleasePlan: releasePlan, 152 ReleasePlanAdmission: releasePlanAdmission, 153 Snapshot: snapshot, 154 }, 155 }, 156 { 157 ContextKey: loader.RoleBindingContextKey, 158 Resource: roleBinding, 159 }, 160 }) 161 result, err := adapter.EnsureFinalizerIsAdded() 162 Expect(!result.RequeueRequest && result.CancelRequest).To(BeFalse()) 163 Expect(err).NotTo(HaveOccurred()) 164 Expect(adapter.release.Finalizers).To(HaveLen(1)) 165 166 result, err = adapter.EnsureReleaseIsProcessed() 167 Expect(!result.RequeueRequest && result.CancelRequest).To(BeFalse()) 168 Expect(err).NotTo(HaveOccurred()) 169 170 Expect(adapter.client.Delete(adapter.ctx, adapter.release)).To(Succeed()) 171 adapter.release, err = adapter.loader.GetRelease(adapter.ctx, adapter.client, adapter.release.Name, adapter.release.Namespace) 172 Expect(adapter.release).NotTo(BeNil()) 173 Expect(err).NotTo(HaveOccurred()) 174 Expect(adapter.release.DeletionTimestamp).NotTo(BeNil()) 175 176 result, err = adapter.EnsureFinalizersAreCalled() 177 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 178 Expect(err).NotTo(HaveOccurred()) 179 180 pipelineRun, err := adapter.loader.GetManagedReleasePipelineRun(adapter.ctx, adapter.client, adapter.release) 181 Expect(pipelineRun).To(Or(BeNil(), HaveField("DeletionTimestamp", Not(BeNil())))) 182 Expect(err).NotTo(HaveOccurred()) 183 184 _, err = adapter.loader.GetRelease(adapter.ctx, adapter.client, adapter.release.Name, adapter.release.Namespace) 185 Expect(err).To(HaveOccurred()) 186 Expect(errors.IsNotFound(err)).To(BeTrue()) 187 }) 188 }) 189 190 When("EnsureFinalizerIsAdded is called", func() { 191 var adapter *adapter 192 193 AfterEach(func() { 194 _ = adapter.client.Delete(ctx, adapter.release) 195 }) 196 197 BeforeEach(func() { 198 adapter = createReleaseAndAdapter() 199 }) 200 201 It("should add a finalizer to the Release", func() { 202 result, err := adapter.EnsureFinalizerIsAdded() 203 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 204 Expect(err).NotTo(HaveOccurred()) 205 Expect(adapter.release.Finalizers).To(ContainElement(metadata.ReleaseFinalizer)) 206 }) 207 208 It("shouldn't fail if the Release already has the finalizer added", func() { 209 result, err := adapter.EnsureFinalizerIsAdded() 210 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 211 Expect(err).NotTo(HaveOccurred()) 212 Expect(adapter.release.Finalizers).To(ContainElement(metadata.ReleaseFinalizer)) 213 214 result, err = adapter.EnsureFinalizerIsAdded() 215 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 216 Expect(err).NotTo(HaveOccurred()) 217 }) 218 }) 219 220 When("EnsureReleaseIsCompleted is called", func() { 221 var adapter *adapter 222 223 AfterEach(func() { 224 _ = adapter.client.Delete(ctx, adapter.release) 225 }) 226 227 BeforeEach(func() { 228 adapter = createReleaseAndAdapter() 229 adapter.release.MarkReleasing("") 230 }) 231 232 It("should not change the release status if it's set already", func() { 233 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 234 { 235 ContextKey: loader.ReleasePlanAdmissionContextKey, 236 Resource: releasePlanAdmission, 237 }, 238 }) 239 adapter.release.MarkProcessing("") 240 adapter.release.MarkProcessed() 241 adapter.release.MarkReleaseFailed("") 242 result, err := adapter.EnsureReleaseIsCompleted() 243 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 244 Expect(err).NotTo(HaveOccurred()) 245 Expect(adapter.release.HasReleaseFinished()).To(BeTrue()) 246 Expect(adapter.release.IsReleased()).To(BeFalse()) 247 }) 248 249 It("should do nothing if the processing has not completed", func() { 250 result, err := adapter.EnsureReleaseIsCompleted() 251 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 252 Expect(err).NotTo(HaveOccurred()) 253 Expect(adapter.release.HasReleaseFinished()).To(BeFalse()) 254 }) 255 256 It("should complete the release if all the required phases have completed", func() { 257 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 258 { 259 ContextKey: loader.ReleasePlanAdmissionContextKey, 260 Resource: releasePlanAdmission, 261 }, 262 }) 263 adapter.release.MarkProcessing("") 264 adapter.release.MarkProcessed() 265 result, err := adapter.EnsureReleaseIsCompleted() 266 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 267 Expect(err).NotTo(HaveOccurred()) 268 Expect(adapter.release.HasReleaseFinished()).To(BeTrue()) 269 }) 270 }) 271 272 When("EnsureReleaseIsRunning is called", func() { 273 var adapter *adapter 274 275 AfterEach(func() { 276 _ = adapter.client.Delete(ctx, adapter.release) 277 }) 278 279 BeforeEach(func() { 280 adapter = createReleaseAndAdapter() 281 }) 282 283 It("should stop processing if the release has finished", func() { 284 adapter.release.MarkReleasing("") 285 adapter.release.MarkReleased() 286 287 result, err := adapter.EnsureReleaseIsRunning() 288 Expect(!result.RequeueRequest && result.CancelRequest).To(BeTrue()) 289 Expect(err).NotTo(HaveOccurred()) 290 }) 291 292 It("should mark the Release as releasing if it is missing the status", func() { 293 result, err := adapter.EnsureReleaseIsRunning() 294 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 295 Expect(err).NotTo(HaveOccurred()) 296 Expect(adapter.release.IsReleasing()).To(BeTrue()) 297 }) 298 299 It("should do nothing if the release is already running", func() { 300 adapter.release.MarkReleasing("") 301 302 result, err := adapter.EnsureReleaseIsRunning() 303 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 304 Expect(err).NotTo(HaveOccurred()) 305 Expect(adapter.release.IsReleasing()).To(BeTrue()) 306 }) 307 }) 308 309 When("EnsureReleaseIsProcessed is called", func() { 310 var adapter *adapter 311 312 AfterEach(func() { 313 _ = adapter.client.Delete(ctx, adapter.release) 314 }) 315 316 BeforeEach(func() { 317 adapter = createReleaseAndAdapter() 318 adapter.releaseServiceConfig = releaseServiceConfig 319 }) 320 321 It("should do nothing if the Release is already processed", func() { 322 adapter.release.MarkProcessing("") 323 adapter.release.MarkProcessed() 324 325 result, err := adapter.EnsureReleaseIsProcessed() 326 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 327 Expect(err).NotTo(HaveOccurred()) 328 Expect(adapter.release.IsProcessing()).To(BeFalse()) 329 }) 330 331 It("should continue if the PipelineRun exists and the release processing has started", func() { 332 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 333 { 334 ContextKey: loader.ReleasePipelineRunContextKey, 335 Resource: &tektonv1.PipelineRun{ 336 ObjectMeta: metav1.ObjectMeta{ 337 Name: "pipeline-run", 338 Namespace: "default", 339 }, 340 }, 341 }, 342 { 343 ContextKey: loader.RoleBindingContextKey, 344 Resource: roleBinding, 345 }, 346 }) 347 adapter.release.MarkProcessing("") 348 349 result, err := adapter.EnsureReleaseIsProcessed() 350 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 351 Expect(err).NotTo(HaveOccurred()) 352 }) 353 354 It("should register the processing data if the PipelineRun already exists", func() { 355 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 356 { 357 ContextKey: loader.ReleasePipelineRunContextKey, 358 Resource: &tektonv1.PipelineRun{ 359 ObjectMeta: metav1.ObjectMeta{ 360 Name: "pipeline-run", 361 Namespace: "default", 362 }, 363 }, 364 }, 365 { 366 ContextKey: loader.RoleBindingContextKey, 367 Resource: roleBinding, 368 }, 369 { 370 ContextKey: loader.ProcessingResourcesContextKey, 371 Resource: &loader.ProcessingResources{ 372 EnterpriseContractConfigMap: enterpriseContractConfigMap, 373 EnterpriseContractPolicy: enterpriseContractPolicy, 374 ReleasePlanAdmission: releasePlanAdmission, 375 Snapshot: snapshot, 376 }, 377 }, 378 }) 379 380 result, err := adapter.EnsureReleaseIsProcessed() 381 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 382 Expect(err).NotTo(HaveOccurred()) 383 Expect(adapter.release.IsProcessing()).To(BeTrue()) 384 }) 385 386 It("should requeue the Release if any of the resources is not found", func() { 387 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 388 { 389 ContextKey: loader.ProcessingResourcesContextKey, 390 Err: fmt.Errorf("not found"), 391 }, 392 }) 393 394 result, err := adapter.EnsureReleaseIsProcessed() 395 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 396 Expect(err).To(HaveOccurred()) 397 }) 398 399 It("should create a RoleBinding if all the required resources are present and none exists in the Release Status", func() { 400 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 401 { 402 ContextKey: loader.ProcessingResourcesContextKey, 403 Resource: &loader.ProcessingResources{ 404 EnterpriseContractConfigMap: enterpriseContractConfigMap, 405 EnterpriseContractPolicy: enterpriseContractPolicy, 406 ReleasePlan: releasePlan, 407 ReleasePlanAdmission: releasePlanAdmission, 408 Snapshot: snapshot, 409 }, 410 }, 411 { 412 ContextKey: loader.RoleBindingContextKey, 413 Resource: nil, 414 }, 415 }) 416 417 Expect(adapter.release.Status.Processing.RoleBinding).To(BeEmpty()) 418 result, err := adapter.EnsureReleaseIsProcessed() 419 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 420 Expect(err).NotTo(HaveOccurred()) 421 422 // Reset MockedContext so that the RoleBinding that was just created can be fetched 423 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 424 { 425 ContextKey: loader.ProcessingResourcesContextKey, 426 Resource: &loader.ProcessingResources{ 427 EnterpriseContractConfigMap: enterpriseContractConfigMap, 428 EnterpriseContractPolicy: enterpriseContractPolicy, 429 ReleasePlan: releasePlan, 430 ReleasePlanAdmission: releasePlanAdmission, 431 Snapshot: snapshot, 432 }, 433 }, 434 }) 435 436 roleBinding, err := adapter.loader.GetRoleBindingFromReleaseStatus(adapter.ctx, adapter.client, adapter.release) 437 Expect(roleBinding).NotTo(BeNil()) 438 Expect(err).NotTo(HaveOccurred()) 439 Expect(adapter.client.Delete(adapter.ctx, roleBinding)).To(Succeed()) 440 // Still need to cleanup the PipelineRun 441 pipelineRun, err := adapter.loader.GetManagedReleasePipelineRun(adapter.ctx, adapter.client, adapter.release) 442 Expect(pipelineRun).NotTo(BeNil()) 443 Expect(err).NotTo(HaveOccurred()) 444 Expect(adapter.client.Delete(adapter.ctx, pipelineRun)).To(Succeed()) 445 }) 446 447 It("should not create a RoleBinding if the ReleasePlanAdmission has no ServiceAccount set", func() { 448 newReleasePlanAdmission := &v1alpha1.ReleasePlanAdmission{ 449 ObjectMeta: metav1.ObjectMeta{ 450 Name: "release-plan-admission", 451 Namespace: "default", 452 }, 453 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 454 Applications: []string{application.Name}, 455 Origin: "default", 456 Pipeline: &tektonutils.Pipeline{ 457 PipelineRef: tektonutils.PipelineRef{ 458 Resolver: "git", 459 Params: []tektonutils.Param{ 460 {Name: "url", Value: "my-url"}, 461 {Name: "revision", Value: "my-revision"}, 462 {Name: "pathInRepo", Value: "my-path"}, 463 }, 464 }, 465 }, 466 Policy: enterpriseContractPolicy.Name, 467 }, 468 } 469 newReleasePlanAdmission.Kind = "ReleasePlanAdmission" 470 471 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 472 { 473 ContextKey: loader.ProcessingResourcesContextKey, 474 Resource: &loader.ProcessingResources{ 475 EnterpriseContractConfigMap: enterpriseContractConfigMap, 476 EnterpriseContractPolicy: enterpriseContractPolicy, 477 ReleasePlan: releasePlan, 478 ReleasePlanAdmission: newReleasePlanAdmission, 479 Snapshot: snapshot, 480 }, 481 }, 482 { 483 ContextKey: loader.RoleBindingContextKey, 484 Resource: nil, 485 }, 486 }) 487 488 Expect(adapter.release.Status.Processing.RoleBinding).To(BeEmpty()) 489 result, err := adapter.EnsureReleaseIsProcessed() 490 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 491 Expect(err).NotTo(HaveOccurred()) 492 493 // Reset MockedContext so that the RoleBinding can be fetched if it exists 494 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 495 { 496 ContextKey: loader.ProcessingResourcesContextKey, 497 Resource: &loader.ProcessingResources{ 498 EnterpriseContractConfigMap: enterpriseContractConfigMap, 499 EnterpriseContractPolicy: enterpriseContractPolicy, 500 ReleasePlan: releasePlan, 501 ReleasePlanAdmission: newReleasePlanAdmission, 502 Snapshot: snapshot, 503 }, 504 }, 505 }) 506 507 roleBinding, err := adapter.loader.GetRoleBindingFromReleaseStatus(adapter.ctx, adapter.client, adapter.release) 508 Expect(roleBinding).To(BeNil()) 509 Expect(err).To(HaveOccurred()) 510 // Still need to cleanup the PipelineRun 511 pipelineRun, err := adapter.loader.GetManagedReleasePipelineRun(adapter.ctx, adapter.client, adapter.release) 512 Expect(pipelineRun).NotTo(BeNil()) 513 Expect(err).NotTo(HaveOccurred()) 514 Expect(adapter.client.Delete(adapter.ctx, pipelineRun)).To(Succeed()) 515 }) 516 517 It("should create a pipelineRun and register the processing data if all the required resources are present", func() { 518 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 519 { 520 ContextKey: loader.ProcessingResourcesContextKey, 521 Resource: &loader.ProcessingResources{ 522 EnterpriseContractConfigMap: enterpriseContractConfigMap, 523 EnterpriseContractPolicy: enterpriseContractPolicy, 524 ReleasePlan: releasePlan, 525 ReleasePlanAdmission: releasePlanAdmission, 526 Snapshot: snapshot, 527 }, 528 }, 529 { 530 ContextKey: loader.RoleBindingContextKey, 531 Resource: roleBinding, 532 }, 533 }) 534 535 result, err := adapter.EnsureReleaseIsProcessed() 536 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 537 Expect(err).NotTo(HaveOccurred()) 538 Expect(adapter.release.IsProcessing()).To(BeTrue()) 539 540 pipelineRun, err := adapter.loader.GetManagedReleasePipelineRun(adapter.ctx, adapter.client, adapter.release) 541 Expect(pipelineRun).NotTo(BeNil()) 542 Expect(err).NotTo(HaveOccurred()) 543 Expect(adapter.client.Delete(adapter.ctx, pipelineRun)).To(Succeed()) 544 }) 545 }) 546 547 When("EnsureReleaseIsValid is called", func() { 548 var adapter *adapter 549 550 AfterEach(func() { 551 _ = adapter.client.Delete(ctx, adapter.release) 552 }) 553 554 BeforeEach(func() { 555 adapter = createReleaseAndAdapter() 556 adapter.release.MarkReleasing("") 557 Expect(adapter.client.Status().Update(adapter.ctx, adapter.release)).To(Succeed()) 558 }) 559 560 It("should mark the release as validated if all checks pass", func() { 561 adapter.validations = []controller.ValidationFunction{} 562 563 result, err := adapter.EnsureReleaseIsValid() 564 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 565 Expect(err).NotTo(HaveOccurred()) 566 Expect(adapter.release.IsValid()).To(BeTrue()) 567 Expect(adapter.release.HasReleaseFinished()).To(BeFalse()) 568 }) 569 570 It("should mark the release as failed if a validation fails", func() { 571 adapter.validations = []controller.ValidationFunction{ 572 func() *controller.ValidationResult { 573 return &controller.ValidationResult{Valid: false} 574 }, 575 } 576 577 result, err := adapter.EnsureReleaseIsValid() 578 Expect(!result.RequeueRequest && result.CancelRequest).To(BeTrue()) 579 Expect(err).NotTo(HaveOccurred()) 580 Expect(adapter.release.IsValid()).To(BeFalse()) 581 Expect(adapter.release.HasReleaseFinished()).To(BeTrue()) 582 }) 583 584 It("should requeue the release if a validation fails with an error", func() { 585 adapter.validations = []controller.ValidationFunction{ 586 func() *controller.ValidationResult { 587 return &controller.ValidationResult{Err: fmt.Errorf("internal error")} 588 }, 589 } 590 591 result, err := adapter.EnsureReleaseIsValid() 592 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 593 Expect(err).To(HaveOccurred()) 594 Expect(adapter.release.HasReleaseFinished()).To(BeFalse()) 595 }) 596 597 It("does not clear the release status", func() { 598 adapter.validations = []controller.ValidationFunction{} 599 600 result, err := adapter.EnsureReleaseIsValid() 601 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 602 Expect(err).NotTo(HaveOccurred()) 603 Expect(adapter.release.Status.StartTime).NotTo(BeNil()) 604 }) 605 }) 606 607 When("EnsureReleaseProcessingIsTracked is called", func() { 608 var adapter *adapter 609 610 AfterEach(func() { 611 _ = adapter.client.Delete(ctx, adapter.release) 612 }) 613 614 BeforeEach(func() { 615 adapter = createReleaseAndAdapter() 616 }) 617 618 It("should continue if the Release processing has not started", func() { 619 result, err := adapter.EnsureReleaseProcessingIsTracked() 620 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 621 Expect(err).NotTo(HaveOccurred()) 622 }) 623 624 It("should continue if the Release processing has finished", func() { 625 adapter.release.MarkProcessing("") 626 adapter.release.MarkProcessed() 627 628 result, err := adapter.EnsureReleaseProcessingIsTracked() 629 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 630 Expect(err).NotTo(HaveOccurred()) 631 }) 632 633 It("should track the status if the PipelineRun exists", func() { 634 adapter.release.MarkProcessing("") 635 636 pipelineRun := &tektonv1.PipelineRun{ 637 ObjectMeta: metav1.ObjectMeta{ 638 Name: "pipeline-run", 639 Namespace: "default", 640 }, 641 } 642 pipelineRun.Status.MarkSucceeded("", "") 643 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 644 { 645 ContextKey: loader.ReleasePipelineRunContextKey, 646 Resource: pipelineRun, 647 }, 648 { 649 ContextKey: loader.RoleBindingContextKey, 650 }, 651 }) 652 653 result, err := adapter.EnsureReleaseProcessingIsTracked() 654 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 655 Expect(err).NotTo(HaveOccurred()) 656 Expect(adapter.release.HasProcessingFinished()).To(BeTrue()) 657 }) 658 659 It("should continue if the PipelineRun doesn't exist", func() { 660 adapter.release.MarkProcessing("") 661 662 result, err := adapter.EnsureReleaseProcessingIsTracked() 663 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 664 Expect(err).NotTo(HaveOccurred()) 665 }) 666 }) 667 668 When("EnsureReleaseExpirationTimeIsAdded is called", func() { 669 var adapter *adapter 670 var newReleasePlan *v1alpha1.ReleasePlan 671 672 AfterEach(func() { 673 _ = adapter.client.Delete(ctx, adapter.release) 674 }) 675 676 BeforeEach(func() { 677 adapter = createReleaseAndAdapter() 678 newReleasePlan = &v1alpha1.ReleasePlan{ 679 ObjectMeta: metav1.ObjectMeta{ 680 Name: "release-plan", 681 Namespace: "default", 682 }, 683 Spec: v1alpha1.ReleasePlanSpec{ 684 Application: application.Name, 685 Target: "default", 686 ReleaseGracePeriodDays: 6, 687 }, 688 } 689 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 690 { 691 ContextKey: loader.ReleasePlanContextKey, 692 Resource: newReleasePlan, 693 }, 694 }) 695 }) 696 697 It("should set the ExpirationTime with the value of Release's GracePeriodDays and then continue", func() { 698 expireDays := time.Duration(3) 699 adapter.release.Spec.GracePeriodDays = 3 700 creationTime := adapter.release.CreationTimestamp 701 expectedExpirationTime := &metav1.Time{Time: creationTime.Add(time.Hour * 24 * expireDays)} 702 703 result, err := adapter.EnsureReleaseExpirationTimeIsAdded() 704 Expect(adapter.release.Status.ExpirationTime).To(Equal(expectedExpirationTime)) 705 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 706 Expect(err).NotTo(HaveOccurred()) 707 }) 708 709 It("should set the ExpirationTime with the value of ReleasePlan's ReleaseGracePeriodDays and then continue", func() { 710 expireDays := time.Duration(newReleasePlan.Spec.ReleaseGracePeriodDays) 711 creationTime := adapter.release.CreationTimestamp 712 expectedExpirationTime := &metav1.Time{Time: creationTime.Add(time.Hour * 24 * expireDays)} 713 714 result, err := adapter.EnsureReleaseExpirationTimeIsAdded() 715 Expect(adapter.release.Status.ExpirationTime).To(Equal(expectedExpirationTime)) 716 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 717 Expect(err).NotTo(HaveOccurred()) 718 }) 719 720 It("should not change the ExpirationTime if it is already set", func() { 721 expireDays := time.Duration(5) 722 creationTime := adapter.release.CreationTimestamp 723 expectedExpirationTime := &metav1.Time{Time: creationTime.Add(time.Hour * 24 * expireDays)} 724 725 adapter.release.Status.ExpirationTime = expectedExpirationTime 726 result, err := adapter.EnsureReleaseExpirationTimeIsAdded() 727 Expect(adapter.release.Status.ExpirationTime).To(Equal(expectedExpirationTime)) 728 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 729 Expect(err).NotTo(HaveOccurred()) 730 }) 731 }) 732 733 When("EnsureReleaseProcessingResourcesAreCleanedUp is called", func() { 734 var adapter *adapter 735 736 AfterEach(func() { 737 _ = adapter.client.Delete(ctx, adapter.release) 738 }) 739 740 BeforeEach(func() { 741 adapter = createReleaseAndAdapter() 742 }) 743 744 It("should continue if the Release processing has not finished", func() { 745 result, err := adapter.EnsureReleaseProcessingResourcesAreCleanedUp() 746 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 747 Expect(err).NotTo(HaveOccurred()) 748 }) 749 750 It("should requeue the release if an error occurs fetching the managed pipelineRun", func() { 751 adapter.release.MarkProcessing("") 752 adapter.release.MarkProcessed() 753 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 754 { 755 ContextKey: loader.ReleasePipelineRunContextKey, 756 Err: fmt.Errorf("error"), 757 }, 758 }) 759 result, err := adapter.EnsureReleaseProcessingResourcesAreCleanedUp() 760 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 761 Expect(err).To(HaveOccurred()) 762 }) 763 764 It("should requeue the release if an error occurs fetching the roleBinding", func() { 765 adapter.release.MarkProcessing("") 766 adapter.release.MarkProcessed() 767 pipelineRun := &tektonv1.PipelineRun{ 768 ObjectMeta: metav1.ObjectMeta{ 769 Name: "pipeline-run", 770 Namespace: "default", 771 }, 772 } 773 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 774 { 775 ContextKey: loader.ReleasePipelineRunContextKey, 776 Resource: pipelineRun, 777 }, 778 { 779 ContextKey: loader.RoleBindingContextKey, 780 Err: fmt.Errorf("error"), 781 }, 782 }) 783 adapter.release.Status.Processing.RoleBinding = "one/two" 784 result, err := adapter.EnsureReleaseProcessingResourcesAreCleanedUp() 785 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 786 Expect(err).To(HaveOccurred()) 787 }) 788 789 It("should call cleanupManagedPipelineRunResources if all the resources are present", func() { 790 adapter.release.MarkProcessing("") 791 adapter.release.MarkProcessed() 792 pipelineRun := &tektonv1.PipelineRun{ 793 ObjectMeta: metav1.ObjectMeta{ 794 Name: "pipeline-run", 795 Namespace: "default", 796 }, 797 } 798 newRoleBinding := roleBinding.DeepCopy() 799 800 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 801 { 802 ContextKey: loader.ReleasePipelineRunContextKey, 803 Resource: pipelineRun, 804 }, 805 { 806 ContextKey: loader.RoleBindingContextKey, 807 Resource: newRoleBinding, 808 }, 809 }) 810 adapter.release.Status.Processing.RoleBinding = fmt.Sprintf("%s%c%s", 811 newRoleBinding.Namespace, types.Separator, newRoleBinding.Name) 812 813 result, err := adapter.EnsureReleaseProcessingResourcesAreCleanedUp() 814 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 815 Expect(err).NotTo(HaveOccurred()) 816 }) 817 }) 818 819 When("cleanupProcessingResources is called", func() { 820 var adapter *adapter 821 822 AfterEach(func() { 823 _ = adapter.client.Delete(ctx, adapter.release) 824 }) 825 826 BeforeEach(func() { 827 adapter = createReleaseAndAdapter() 828 }) 829 830 It("removes the roleBinding if present", func() { 831 newRoleBinding := &rbac.RoleBinding{ 832 ObjectMeta: metav1.ObjectMeta{ 833 Name: "new-role-binding", 834 Namespace: "default", 835 }, 836 RoleRef: rbac.RoleRef{ 837 APIGroup: rbac.GroupName, 838 Kind: "ClusterRole", 839 Name: "clusterrole", 840 }, 841 } 842 // The resource needs to be created as it will get patched 843 Expect(adapter.client.Create(adapter.ctx, newRoleBinding)).To(Succeed()) 844 845 err := adapter.cleanupProcessingResources(nil, newRoleBinding) 846 Expect(err).NotTo(HaveOccurred()) 847 848 checkRoleBinding := &rbac.RoleBinding{} 849 err = toolkit.GetObject(newRoleBinding.Name, newRoleBinding.Namespace, adapter.client, adapter.ctx, checkRoleBinding) 850 Expect(checkRoleBinding).To(Equal(&rbac.RoleBinding{})) 851 Expect(errors.IsNotFound(err)).To(BeTrue()) 852 }) 853 854 It("removes the pipelineRun finalizer if present", func() { 855 pipelineRun := &tektonv1.PipelineRun{ 856 ObjectMeta: metav1.ObjectMeta{ 857 Name: "pipeline-run", 858 Namespace: "default", 859 Finalizers: []string{metadata.ReleaseFinalizer}, 860 }, 861 } 862 // The resource needs to be created as it will get patched 863 Expect(adapter.client.Create(adapter.ctx, pipelineRun)).To(Succeed()) 864 865 err := adapter.cleanupProcessingResources(pipelineRun, nil) 866 Expect(err).NotTo(HaveOccurred()) 867 Expect(pipelineRun.Finalizers).To(BeEmpty()) 868 869 // Clean up at the end 870 Expect(adapter.client.Delete(adapter.ctx, pipelineRun)).To(Succeed()) 871 }) 872 873 It("should not error if either resource is nil", func() { 874 err := adapter.cleanupProcessingResources(nil, nil) 875 Expect(err).NotTo(HaveOccurred()) 876 }) 877 }) 878 879 When("createManagedPipelineRun is called", func() { 880 var ( 881 adapter *adapter 882 pipelineRun *tektonv1.PipelineRun 883 ) 884 885 AfterEach(func() { 886 _ = adapter.client.Delete(ctx, adapter.release) 887 888 Expect(k8sClient.Delete(ctx, pipelineRun)).To(Succeed()) 889 }) 890 891 BeforeEach(func() { 892 adapter = createReleaseAndAdapter() 893 adapter.releaseServiceConfig = releaseServiceConfig 894 resources := &loader.ProcessingResources{ 895 ReleasePlan: releasePlan, 896 ReleasePlanAdmission: releasePlanAdmission, 897 EnterpriseContractConfigMap: enterpriseContractConfigMap, 898 EnterpriseContractPolicy: enterpriseContractPolicy, 899 Snapshot: snapshot, 900 } 901 902 var err error 903 pipelineRun, err = adapter.createManagedPipelineRun(resources) 904 Expect(pipelineRun).NotTo(BeNil()) 905 Expect(err).NotTo(HaveOccurred()) 906 }) 907 908 It("returns a PipelineRun with the right prefix", func() { 909 Expect(reflect.TypeOf(pipelineRun)).To(Equal(reflect.TypeOf(&tektonv1.PipelineRun{}))) 910 Expect(pipelineRun.Name).To(HavePrefix("managed")) 911 }) 912 913 It("has the release reference", func() { 914 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", strings.ToLower(adapter.release.Kind)))) 915 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", 916 fmt.Sprintf("%s%c%s", adapter.release.Namespace, types.Separator, adapter.release.Name)))) 917 }) 918 919 It("has the releasePlan reference", func() { 920 name := []rune(releasePlan.Kind) 921 name[0] = unicode.ToLower(name[0]) 922 923 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", string(name)))) 924 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", 925 fmt.Sprintf("%s%c%s", releasePlan.Namespace, types.Separator, releasePlan.Name)))) 926 }) 927 928 It("has the releasePlanAdmission reference", func() { 929 name := []rune(releasePlanAdmission.Kind) 930 name[0] = unicode.ToLower(name[0]) 931 932 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", string(name)))) 933 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", 934 fmt.Sprintf("%s%c%s", releasePlanAdmission.Namespace, types.Separator, releasePlanAdmission.Name)))) 935 }) 936 937 It("has the releaseServiceConfig reference", func() { 938 name := []rune(releaseServiceConfig.Kind) 939 name[0] = unicode.ToLower(name[0]) 940 941 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", string(name)))) 942 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", 943 fmt.Sprintf("%s%c%s", releaseServiceConfig.Namespace, types.Separator, releaseServiceConfig.Name)))) 944 }) 945 946 It("has the snapshot reference", func() { 947 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", strings.ToLower(snapshot.Kind)))) 948 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", 949 fmt.Sprintf("%s%c%s", snapshot.Namespace, types.Separator, snapshot.Name)))) 950 }) 951 952 It("has owner annotations", func() { 953 Expect(pipelineRun.GetAnnotations()[handler.NamespacedNameAnnotation]).To(ContainSubstring(adapter.release.Name)) 954 Expect(pipelineRun.GetAnnotations()[handler.TypeAnnotation]).To(ContainSubstring("Release")) 955 }) 956 957 It("has release labels", func() { 958 Expect(pipelineRun.GetLabels()[metadata.PipelinesTypeLabel]).To(Equal(metadata.ManagedPipelineType)) 959 Expect(pipelineRun.GetLabels()[metadata.ReleaseNameLabel]).To(Equal(adapter.release.Name)) 960 Expect(pipelineRun.GetLabels()[metadata.ReleaseNamespaceLabel]).To(Equal(testNamespace)) 961 Expect(pipelineRun.GetLabels()[metadata.ReleaseSnapshotLabel]).To(Equal(adapter.release.Spec.Snapshot)) 962 }) 963 964 It("references the pipeline specified in the ReleasePlanAdmission", func() { 965 var pipelineUrl string 966 resolverParams := pipelineRun.Spec.PipelineRef.ResolverRef.Params 967 for i := range resolverParams { 968 if resolverParams[i].Name == "url" { 969 pipelineUrl = resolverParams[i].Value.StringVal 970 } 971 } 972 Expect(pipelineUrl).To(Equal(releasePlanAdmission.Spec.Pipeline.PipelineRef.Params[0].Value)) 973 }) 974 975 It("contains a parameter with the taskGitUrl", func() { 976 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", "taskGitUrl"))) 977 var url string 978 resolverParams := pipelineRun.Spec.PipelineRef.ResolverRef.Params 979 for i := range resolverParams { 980 if resolverParams[i].Name == "url" { 981 url = resolverParams[i].Value.StringVal 982 } 983 } 984 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", url))) 985 }) 986 987 It("contains a parameter with the taskGitRevision", func() { 988 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", "taskGitRevision"))) 989 var revision string 990 resolverParams := pipelineRun.Spec.PipelineRef.ResolverRef.Params 991 for i := range resolverParams { 992 if resolverParams[i].Name == "revision" { 993 revision = resolverParams[i].Value.StringVal 994 } 995 } 996 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", revision))) 997 }) 998 999 It("contains the proper timeout value", func() { 1000 Expect(pipelineRun.Spec.Timeouts.Pipeline).To(Equal(releasePlanAdmission.Spec.Pipeline.Timeouts.Pipeline)) 1001 }) 1002 1003 It("contains a parameter with the verify ec task bundle", func() { 1004 bundle := enterpriseContractConfigMap.Data["verify_ec_task_bundle"] 1005 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", Equal(string(bundle))))) 1006 }) 1007 1008 It("contains a parameter with the json representation of the EnterpriseContractPolicy", func() { 1009 jsonSpec, _ := json.Marshal(enterpriseContractPolicy.Spec) 1010 Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", Equal(string(jsonSpec))))) 1011 }) 1012 }) 1013 1014 When("createRoleBindingForClusterRole is called", func() { 1015 var adapter *adapter 1016 1017 AfterEach(func() { 1018 _ = adapter.client.Delete(ctx, adapter.release) 1019 }) 1020 1021 BeforeEach(func() { 1022 adapter = createReleaseAndAdapter() 1023 }) 1024 1025 It("fails when the releasePlanAdmission has no serviceAccount", func() { 1026 newReleasePlanAdmission := &v1alpha1.ReleasePlanAdmission{ 1027 ObjectMeta: metav1.ObjectMeta{ 1028 Name: "release-plan-admission", 1029 Namespace: "default", 1030 }, 1031 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 1032 Applications: []string{application.Name}, 1033 Origin: "default", 1034 Pipeline: &tektonutils.Pipeline{ 1035 PipelineRef: tektonutils.PipelineRef{ 1036 Resolver: "git", 1037 Params: []tektonutils.Param{ 1038 {Name: "url", Value: "my-url"}, 1039 {Name: "revision", Value: "my-revision"}, 1040 {Name: "pathInRepo", Value: "my-path"}, 1041 }, 1042 }, 1043 }, 1044 Policy: enterpriseContractPolicy.Name, 1045 }, 1046 } 1047 roleBinding, err := adapter.createRoleBindingForClusterRole("foo", newReleasePlanAdmission) 1048 Expect(err).To(HaveOccurred()) 1049 Expect(roleBinding).To(BeNil()) 1050 Expect(err.Error()).To(ContainSubstring("is invalid")) 1051 }) 1052 1053 It("creates a new roleBinding", func() { 1054 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1055 { 1056 ContextKey: loader.ReleasePlanAdmissionContextKey, 1057 Resource: releasePlanAdmission, 1058 }, 1059 }) 1060 1061 roleBinding, err := adapter.createRoleBindingForClusterRole("foo", releasePlanAdmission) 1062 Expect(err).NotTo(HaveOccurred()) 1063 Expect(roleBinding).NotTo(BeNil()) 1064 Expect(roleBinding.RoleRef.Name).To(Equal("foo")) 1065 1066 Expect(k8sClient.Delete(ctx, roleBinding)).Should(Succeed()) 1067 }) 1068 }) 1069 1070 When("finalizeRelease is called", func() { 1071 var adapter *adapter 1072 1073 AfterEach(func() { 1074 _ = adapter.client.Delete(ctx, adapter.release) 1075 }) 1076 1077 BeforeEach(func() { 1078 adapter = createReleaseAndAdapter() 1079 }) 1080 1081 It("finalizes the Release successfully", func() { 1082 Expect(adapter.finalizeRelease()).To(Succeed()) 1083 }) 1084 1085 It("finalizes the Release and deletes the PipelineRun", func() { 1086 adapter.releaseServiceConfig = releaseServiceConfig 1087 resources := &loader.ProcessingResources{ 1088 ReleasePlan: releasePlan, 1089 ReleasePlanAdmission: releasePlanAdmission, 1090 EnterpriseContractConfigMap: enterpriseContractConfigMap, 1091 EnterpriseContractPolicy: enterpriseContractPolicy, 1092 Snapshot: snapshot, 1093 } 1094 pipelineRun, err := adapter.createManagedPipelineRun(resources) 1095 Expect(pipelineRun).NotTo(BeNil()) 1096 Expect(err).NotTo(HaveOccurred()) 1097 1098 Expect(adapter.finalizeRelease()).To(Succeed()) 1099 pipelineRun, err = adapter.loader.GetManagedReleasePipelineRun(adapter.ctx, adapter.client, adapter.release) 1100 Expect(err).NotTo(HaveOccurred()) 1101 Expect(pipelineRun).To(BeNil()) 1102 }) 1103 }) 1104 1105 When("getEmptyReleaseServiceConfig is called", func() { 1106 var adapter *adapter 1107 1108 AfterEach(func() { 1109 _ = adapter.client.Delete(ctx, adapter.release) 1110 }) 1111 1112 BeforeEach(func() { 1113 adapter = createReleaseAndAdapter() 1114 }) 1115 1116 It("should return a ReleaseServiceConfig without Spec and with the right ObjectMeta and Kind set", func() { 1117 releaseServiceConfig := adapter.getEmptyReleaseServiceConfig("namespace") 1118 Expect(releaseServiceConfig).NotTo(BeNil()) 1119 Expect(releaseServiceConfig.Name).To(Equal(v1alpha1.ReleaseServiceConfigResourceName)) 1120 Expect(releaseServiceConfig.Namespace).To(Equal("namespace")) 1121 Expect(releaseServiceConfig.Kind).To(Equal("ReleaseServiceConfig")) 1122 }) 1123 }) 1124 1125 When("registerProcessingData is called", func() { 1126 var adapter *adapter 1127 1128 AfterEach(func() { 1129 _ = adapter.client.Delete(ctx, adapter.release) 1130 }) 1131 1132 BeforeEach(func() { 1133 adapter = createReleaseAndAdapter() 1134 }) 1135 1136 It("does nothing if there is no PipelineRun", func() { 1137 Expect(adapter.registerProcessingData(nil, nil)).To(Succeed()) 1138 Expect(adapter.release.Status.Processing.PipelineRun).To(BeEmpty()) 1139 }) 1140 1141 It("registers the Release processing data", func() { 1142 pipelineRun := &tektonv1.PipelineRun{ 1143 ObjectMeta: metav1.ObjectMeta{ 1144 Name: "pipeline-run", 1145 Namespace: "default", 1146 }, 1147 } 1148 roleBinding := &rbac.RoleBinding{ 1149 ObjectMeta: metav1.ObjectMeta{ 1150 Name: "role-binding", 1151 Namespace: "default", 1152 }, 1153 } 1154 Expect(adapter.registerProcessingData(pipelineRun, roleBinding)).To(Succeed()) 1155 Expect(adapter.release.Status.Processing.PipelineRun).To(Equal(fmt.Sprintf("%s%c%s", 1156 pipelineRun.Namespace, types.Separator, pipelineRun.Name))) 1157 Expect(adapter.release.Status.Processing.RoleBinding).To(Equal(fmt.Sprintf("%s%c%s", 1158 roleBinding.Namespace, types.Separator, roleBinding.Name))) 1159 Expect(adapter.release.Status.Target).To(Equal(pipelineRun.Namespace)) 1160 Expect(adapter.release.IsProcessing()).To(BeTrue()) 1161 }) 1162 1163 It("does not set RoleBinding when no RoleBinding is passed", func() { 1164 pipelineRun := &tektonv1.PipelineRun{ 1165 ObjectMeta: metav1.ObjectMeta{ 1166 Name: "pipeline-run", 1167 Namespace: "default", 1168 }, 1169 } 1170 1171 Expect(adapter.registerProcessingData(pipelineRun, nil)).To(Succeed()) 1172 Expect(adapter.release.Status.Processing.RoleBinding).To(BeEmpty()) 1173 Expect(adapter.release.IsProcessing()).To(BeTrue()) 1174 }) 1175 }) 1176 1177 When("registerProcessingStatus is called", func() { 1178 var adapter *adapter 1179 1180 AfterEach(func() { 1181 _ = adapter.client.Delete(ctx, adapter.release) 1182 }) 1183 1184 BeforeEach(func() { 1185 adapter = createReleaseAndAdapter() 1186 }) 1187 1188 It("does nothing if there is no PipelineRun", func() { 1189 Expect(adapter.registerProcessingStatus(nil)).To(Succeed()) 1190 Expect(adapter.release.Status.Processing.CompletionTime).To(BeNil()) 1191 }) 1192 1193 It("does nothing if the PipelineRun is not done", func() { 1194 pipelineRun := &tektonv1.PipelineRun{} 1195 Expect(adapter.registerProcessingStatus(pipelineRun)).To(Succeed()) 1196 Expect(adapter.release.Status.Processing.CompletionTime).To(BeNil()) 1197 }) 1198 1199 It("sets the Release as succeeded if the PipelineRun succeeded", func() { 1200 pipelineRun := &tektonv1.PipelineRun{} 1201 pipelineRun.Status.MarkSucceeded("", "") 1202 adapter.release.MarkProcessing("") 1203 1204 Expect(adapter.registerProcessingStatus(pipelineRun)).To(Succeed()) 1205 Expect(adapter.release.IsProcessed()).To(BeTrue()) 1206 }) 1207 1208 It("sets the Release as failed if the PipelineRun didn't succeed", func() { 1209 pipelineRun := &tektonv1.PipelineRun{} 1210 pipelineRun.Status.MarkFailed("", "") 1211 adapter.release.MarkProcessing("") 1212 1213 Expect(adapter.registerProcessingStatus(pipelineRun)).To(Succeed()) 1214 Expect(adapter.release.HasProcessingFinished()).To(BeTrue()) 1215 Expect(adapter.release.IsProcessed()).To(BeFalse()) 1216 }) 1217 }) 1218 1219 When("calling syncResources", func() { 1220 var adapter *adapter 1221 1222 AfterEach(func() { 1223 _ = adapter.client.Delete(ctx, adapter.release) 1224 }) 1225 1226 BeforeEach(func() { 1227 adapter = createReleaseAndAdapter() 1228 }) 1229 1230 It("fails if there's no active ReleasePlanAdmission", func() { 1231 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1232 { 1233 ContextKey: loader.ReleasePlanAdmissionContextKey, 1234 Err: fmt.Errorf("not found"), 1235 }, 1236 }) 1237 1238 Expect(adapter.syncResources()).NotTo(Succeed()) 1239 }) 1240 1241 It("fails if there's no Snapshot", func() { 1242 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1243 { 1244 ContextKey: loader.ReleasePlanAdmissionContextKey, 1245 }, 1246 { 1247 ContextKey: loader.SnapshotContextKey, 1248 Err: fmt.Errorf("not found"), 1249 }, 1250 }) 1251 1252 Expect(adapter.syncResources()).NotTo(Succeed()) 1253 }) 1254 1255 It("should sync resources properly", func() { 1256 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1257 { 1258 ContextKey: loader.ReleasePlanAdmissionContextKey, 1259 Resource: releasePlanAdmission, 1260 }, 1261 }) 1262 1263 Expect(adapter.syncResources()).To(Succeed()) 1264 }) 1265 }) 1266 1267 When("calling validateAuthor", func() { 1268 var adapter *adapter 1269 var conditionMsg string 1270 1271 AfterEach(func() { 1272 _ = adapter.client.Delete(ctx, adapter.release) 1273 }) 1274 1275 BeforeEach(func() { 1276 adapter = createReleaseAndAdapter() 1277 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1278 { 1279 ContextKey: loader.ReleasePlanContextKey, 1280 Resource: releasePlan, 1281 }, 1282 }) 1283 }) 1284 1285 It("returns valid and no error if the release is already attributed", func() { 1286 adapter.release.Status.Attribution.Author = "user" 1287 result := adapter.validateAuthor() 1288 Expect(result.Valid).To(BeTrue()) 1289 Expect(result.Err).NotTo(HaveOccurred()) 1290 }) 1291 1292 It("should return invalid and no error if the ReleasePlan is not found", func() { 1293 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1294 { 1295 ContextKey: loader.ReleasePlanContextKey, 1296 Err: errors.NewNotFound(schema.GroupResource{}, ""), 1297 }, 1298 }) 1299 1300 result := adapter.validateAuthor() 1301 Expect(result.Valid).To(BeFalse()) 1302 Expect(result.Err).NotTo(HaveOccurred()) 1303 Expect(adapter.release.IsValid()).To(BeFalse()) 1304 }) 1305 1306 When("the release has the automated label", func() { 1307 AfterEach(func() { 1308 _ = adapter.client.Delete(ctx, adapter.release) 1309 }) 1310 1311 BeforeEach(func() { 1312 adapter = createReleaseAndAdapter() 1313 adapter.release.Labels = map[string]string{ 1314 metadata.AutomatedLabel: "true", 1315 } 1316 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1317 { 1318 ContextKey: loader.ReleasePlanContextKey, 1319 Resource: releasePlan, 1320 }, 1321 }) 1322 }) 1323 1324 It("returns invalid and an error if automated label is present but is not set in release status", func() { 1325 result := adapter.validateAuthor() 1326 Expect(result.Valid).To(BeFalse()) 1327 Expect(result.Err).To(HaveOccurred()) 1328 for i := range adapter.release.Status.Conditions { 1329 if adapter.release.Status.Conditions[i].Type == "Validated" { 1330 conditionMsg = adapter.release.Status.Conditions[i].Message 1331 } 1332 } 1333 Expect(conditionMsg).To(Equal("automated not set in status for automated release")) 1334 }) 1335 1336 It("returns invalid if the error appears after 5 minutes of being created", func() { 1337 adapter.release.SetCreationTimestamp(metav1.Time{Time: time.Now().Add(-7 * time.Minute)}) 1338 result := adapter.validateAuthor() 1339 Expect(result.Valid).To(BeFalse()) 1340 Expect(result.Err).NotTo(HaveOccurred()) 1341 for i := range adapter.release.Status.Conditions { 1342 if adapter.release.Status.Conditions[i].Type == "Validated" { 1343 conditionMsg = adapter.release.Status.Conditions[i].Message 1344 } 1345 } 1346 Expect(conditionMsg).To(Equal("automated not set in status for automated release")) 1347 }) 1348 1349 It("returns invalid and an error if the ReleasePlan has no author", func() { 1350 adapter.release.Status.Automated = true 1351 result := adapter.validateAuthor() 1352 Expect(result.Valid).To(BeFalse()) 1353 Expect(result.Err).NotTo(HaveOccurred()) 1354 for i := range adapter.release.Status.Conditions { 1355 if adapter.release.Status.Conditions[i].Type == "Validated" { 1356 conditionMsg = adapter.release.Status.Conditions[i].Message 1357 } 1358 } 1359 Expect(conditionMsg).To(Equal("no author in the ReleasePlan found for automated release")) 1360 }) 1361 1362 It("properly sets the Attribution data in the release status", func() { 1363 adapter.release.Status.Automated = true 1364 releasePlan.Labels = map[string]string{ 1365 metadata.AuthorLabel: "user", 1366 } 1367 result := adapter.validateAuthor() 1368 Expect(result.Valid).To(BeTrue()) 1369 Expect(result.Err).NotTo(HaveOccurred()) 1370 Expect(adapter.release.Status.Attribution.StandingAuthorization).To(BeTrue()) 1371 Expect(adapter.release.Status.Attribution.Author).To(Equal("user")) 1372 }) 1373 }) 1374 1375 It("returns invalid and an error if the Release has the automated label and no author", func() { 1376 adapter.release.Labels = map[string]string{ 1377 metadata.AutomatedLabel: "false", 1378 metadata.AuthorLabel: "", 1379 } 1380 result := adapter.validateAuthor() 1381 Expect(result.Valid).To(BeFalse()) 1382 Expect(result.Err).NotTo(HaveOccurred()) 1383 for i := range adapter.release.Status.Conditions { 1384 if adapter.release.Status.Conditions[i].Type == "Validated" { 1385 conditionMsg = adapter.release.Status.Conditions[i].Message 1386 } 1387 } 1388 Expect(conditionMsg).To(Equal("no author found for manual release")) 1389 }) 1390 1391 It("properly sets the Attribution author in the manual release status", func() { 1392 adapter.release.Labels = map[string]string{ 1393 metadata.AuthorLabel: "user", 1394 } 1395 result := adapter.validateAuthor() 1396 Expect(result.Valid).To(BeTrue()) 1397 Expect(result.Err).NotTo(HaveOccurred()) 1398 Expect(adapter.release.Status.Attribution.StandingAuthorization).To(BeFalse()) 1399 Expect(adapter.release.Status.Attribution.Author).To(Equal("user")) 1400 }) 1401 }) 1402 1403 When("validateProcessingResources is called", func() { 1404 var adapter *adapter 1405 1406 AfterEach(func() { 1407 _ = adapter.client.Delete(ctx, adapter.release) 1408 }) 1409 1410 BeforeEach(func() { 1411 adapter = createReleaseAndAdapter() 1412 adapter.release.MarkReleasing("") 1413 }) 1414 1415 It("should return valid and no error if all the resources are found", func() { 1416 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1417 { 1418 ContextKey: loader.ProcessingResourcesContextKey, 1419 Resource: &loader.ProcessingResources{ 1420 EnterpriseContractConfigMap: enterpriseContractConfigMap, 1421 EnterpriseContractPolicy: enterpriseContractPolicy, 1422 ReleasePlanAdmission: releasePlanAdmission, 1423 Snapshot: snapshot, 1424 }, 1425 }, 1426 }) 1427 1428 result := adapter.validateProcessingResources() 1429 Expect(result.Valid).To(BeTrue()) 1430 Expect(result.Err).NotTo(HaveOccurred()) 1431 }) 1432 1433 It("should return invalid and no error if any of the resources are not found", func() { 1434 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1435 { 1436 ContextKey: loader.ProcessingResourcesContextKey, 1437 Err: errors.NewNotFound(schema.GroupResource{}, ""), 1438 }, 1439 }) 1440 1441 result := adapter.validateProcessingResources() 1442 Expect(result.Valid).To(BeFalse()) 1443 Expect(result.Err).NotTo(HaveOccurred()) 1444 Expect(adapter.release.IsValid()).To(BeFalse()) 1445 }) 1446 1447 It("should return invalid and no error if the ReleasePlanAdmission is found to be disabled", func() { 1448 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1449 { 1450 ContextKey: loader.ReleasePlanAdmissionContextKey, 1451 Err: fmt.Errorf("auto-release label set to false"), 1452 }, 1453 }) 1454 1455 result := adapter.validateProcessingResources() 1456 Expect(result.Valid).To(BeFalse()) 1457 Expect(result.Err).NotTo(HaveOccurred()) 1458 Expect(adapter.release.IsValid()).To(BeFalse()) 1459 }) 1460 1461 It("should return invalid and no error if multiple ReleasePlanAdmissions exist", func() { 1462 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1463 { 1464 ContextKey: loader.ReleasePlanAdmissionContextKey, 1465 Err: fmt.Errorf("multiple ReleasePlanAdmissions found"), 1466 }, 1467 }) 1468 1469 result := adapter.validateProcessingResources() 1470 Expect(result.Valid).To(BeFalse()) 1471 Expect(result.Err).NotTo(HaveOccurred()) 1472 Expect(adapter.release.IsValid()).To(BeFalse()) 1473 }) 1474 1475 It("should return invalid and an error if some other type of error occurs", func() { 1476 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1477 { 1478 ContextKey: loader.ProcessingResourcesContextKey, 1479 Err: fmt.Errorf("internal error"), 1480 Resource: &loader.ProcessingResources{ 1481 ReleasePlanAdmission: releasePlanAdmission, 1482 }, 1483 }, 1484 }) 1485 1486 result := adapter.validateProcessingResources() 1487 Expect(result.Valid).To(BeFalse()) 1488 Expect(result.Err).To(HaveOccurred()) 1489 Expect(adapter.release.IsValid()).To(BeFalse()) 1490 }) 1491 }) 1492 1493 When("validatePipelineRef is called", func() { 1494 var adapter *adapter 1495 1496 AfterEach(func() { 1497 _ = adapter.client.Delete(ctx, adapter.release) 1498 }) 1499 1500 BeforeEach(func() { 1501 adapter = createReleaseAndAdapter() 1502 releaseServiceConfig.Spec = v1alpha1.ReleaseServiceConfigSpec{} 1503 adapter.releaseServiceConfig = releaseServiceConfig 1504 }) 1505 1506 It("should return invalid and no error if the ReleasePlanAdmission is not found", func() { 1507 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1508 { 1509 ContextKey: loader.ReleasePlanAdmissionContextKey, 1510 Err: errors.NewNotFound(schema.GroupResource{}, ""), 1511 }, 1512 }) 1513 1514 result := adapter.validatePipelineRef() 1515 Expect(result.Valid).To(BeFalse()) 1516 Expect(result.Err).NotTo(HaveOccurred()) 1517 Expect(adapter.release.IsValid()).To(BeFalse()) 1518 }) 1519 1520 It("should return invalid and an error if some other type of error occurs when retrieving the ReleasePlanAdmission", func() { 1521 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1522 { 1523 ContextKey: loader.ReleasePlanAdmissionContextKey, 1524 Err: fmt.Errorf("internal error"), 1525 Resource: releasePlanAdmission, 1526 }, 1527 }) 1528 1529 result := adapter.validatePipelineRef() 1530 Expect(result.Valid).To(BeFalse()) 1531 Expect(result.Err).To(HaveOccurred()) 1532 Expect(adapter.release.IsValid()).To(BeFalse()) 1533 }) 1534 1535 It("returns invalid and no error if debug is false and the PipelineRef uses a cluster resolver", func() { 1536 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1537 { 1538 ContextKey: loader.ReleasePlanAdmissionContextKey, 1539 Resource: &v1alpha1.ReleasePlanAdmission{ 1540 ObjectMeta: metav1.ObjectMeta{ 1541 Name: "release-plan-admission", 1542 Namespace: "default", 1543 Labels: map[string]string{ 1544 metadata.AutoReleaseLabel: "true", 1545 }, 1546 }, 1547 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 1548 Applications: []string{application.Name}, 1549 Origin: "default", 1550 Pipeline: &tektonutils.Pipeline{ 1551 PipelineRef: tektonutils.PipelineRef{ 1552 Resolver: "cluster", 1553 Params: []tektonutils.Param{ 1554 {Name: "name", Value: "release-pipeline"}, 1555 {Name: "namespace", Value: "default"}, 1556 {Name: "kind", Value: "pipeline"}, 1557 }, 1558 }, 1559 }, 1560 Policy: enterpriseContractPolicy.Name, 1561 }, 1562 }, 1563 }, 1564 }) 1565 adapter.releaseServiceConfig.Spec.Debug = false 1566 1567 result := adapter.validatePipelineRef() 1568 Expect(result.Valid).To(BeFalse()) 1569 Expect(result.Err).To(BeNil()) 1570 Expect(adapter.release.IsValid()).To(BeFalse()) 1571 }) 1572 1573 It("returns valid and no error if debug mode is enabled in the ReleaseServiceConfig", func() { 1574 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1575 { 1576 ContextKey: loader.ReleasePlanAdmissionContextKey, 1577 Resource: releasePlanAdmission, 1578 }, 1579 }) 1580 adapter.releaseServiceConfig.Spec.Debug = true 1581 1582 result := adapter.validatePipelineRef() 1583 Expect(result.Valid).To(BeTrue()) 1584 Expect(result.Err).To(BeNil()) 1585 }) 1586 1587 It("returns valid and no error if debug mode is disabled and the PipelineRef uses a bundle resolver", func() { 1588 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 1589 { 1590 ContextKey: loader.ReleasePlanAdmissionContextKey, 1591 Resource: releasePlanAdmission, 1592 }, 1593 }) 1594 result := adapter.validatePipelineRef() 1595 Expect(result.Valid).To(BeTrue()) 1596 Expect(result.Err).To(BeNil()) 1597 }) 1598 }) 1599 1600 createReleaseAndAdapter = func() *adapter { 1601 release := &v1alpha1.Release{ 1602 ObjectMeta: metav1.ObjectMeta{ 1603 GenerateName: "release-", 1604 Namespace: "default", 1605 }, 1606 Spec: v1alpha1.ReleaseSpec{ 1607 Snapshot: snapshot.Name, 1608 ReleasePlan: releasePlan.Name, 1609 }, 1610 } 1611 Expect(k8sClient.Create(ctx, release)).To(Succeed()) 1612 release.Kind = "Release" 1613 1614 return newAdapter(ctx, k8sClient, release, loader.NewMockLoader(), &ctrl.Log) 1615 } 1616 1617 createResources = func() { 1618 application = &applicationapiv1alpha1.Application{ 1619 ObjectMeta: metav1.ObjectMeta{ 1620 Name: "application", 1621 Namespace: "default", 1622 }, 1623 Spec: applicationapiv1alpha1.ApplicationSpec{ 1624 DisplayName: "application", 1625 }, 1626 } 1627 Expect(k8sClient.Create(ctx, application)).To(Succeed()) 1628 1629 component = &applicationapiv1alpha1.Component{ 1630 ObjectMeta: metav1.ObjectMeta{ 1631 Name: "component", 1632 Namespace: "default", 1633 }, 1634 Spec: applicationapiv1alpha1.ComponentSpec{ 1635 Application: application.Name, 1636 ComponentName: "component", 1637 }, 1638 } 1639 Expect(k8sClient.Create(ctx, component)).Should(Succeed()) 1640 1641 enterpriseContractConfigMap = &corev1.ConfigMap{ 1642 ObjectMeta: metav1.ObjectMeta{ 1643 Name: "enterprise-contract-cm", 1644 Namespace: "default", 1645 }, 1646 Data: map[string]string{ 1647 "verify_ec_task_bundle": "test-bundle", 1648 }, 1649 } 1650 Expect(k8sClient.Create(ctx, enterpriseContractConfigMap)).Should(Succeed()) 1651 1652 enterpriseContractPolicy = &ecapiv1alpha1.EnterpriseContractPolicy{ 1653 ObjectMeta: metav1.ObjectMeta{ 1654 Name: "enterprise-contract-policy", 1655 Namespace: "default", 1656 }, 1657 Spec: ecapiv1alpha1.EnterpriseContractPolicySpec{ 1658 Sources: []ecapiv1alpha1.Source{ 1659 { 1660 Name: "foo", 1661 }, 1662 }, 1663 }, 1664 } 1665 Expect(k8sClient.Create(ctx, enterpriseContractPolicy)).Should(Succeed()) 1666 enterpriseContractPolicy.Kind = "EnterpriseContractPolicy" 1667 1668 releasePlan = &v1alpha1.ReleasePlan{ 1669 ObjectMeta: metav1.ObjectMeta{ 1670 Name: "release-plan", 1671 Namespace: "default", 1672 }, 1673 Spec: v1alpha1.ReleasePlanSpec{ 1674 Application: application.Name, 1675 Target: "default", 1676 }, 1677 } 1678 Expect(k8sClient.Create(ctx, releasePlan)).To(Succeed()) 1679 releasePlan.Kind = "ReleasePlan" 1680 1681 releaseServiceConfig = &v1alpha1.ReleaseServiceConfig{ 1682 ObjectMeta: metav1.ObjectMeta{ 1683 Name: v1alpha1.ReleaseServiceConfigResourceName, 1684 Namespace: "default", 1685 }, 1686 } 1687 Expect(k8sClient.Create(ctx, releaseServiceConfig)).To(Succeed()) 1688 releaseServiceConfig.Kind = "ReleaseServiceConfig" 1689 1690 releasePlanAdmission = &v1alpha1.ReleasePlanAdmission{ 1691 ObjectMeta: metav1.ObjectMeta{ 1692 Name: "release-plan-admission", 1693 Namespace: "default", 1694 Labels: map[string]string{ 1695 metadata.AutoReleaseLabel: "true", 1696 }, 1697 }, 1698 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 1699 Applications: []string{application.Name}, 1700 Origin: "default", 1701 Pipeline: &tektonutils.Pipeline{ 1702 PipelineRef: tektonutils.PipelineRef{ 1703 Resolver: "git", 1704 Params: []tektonutils.Param{ 1705 {Name: "url", Value: "my-url"}, 1706 {Name: "revision", Value: "my-revision"}, 1707 {Name: "pathInRepo", Value: "my-path"}, 1708 }, 1709 }, 1710 ServiceAccount: "service-account", 1711 Timeouts: tektonv1.TimeoutFields{ 1712 Pipeline: &metav1.Duration{Duration: 1 * time.Hour}, 1713 }, 1714 }, 1715 Policy: enterpriseContractPolicy.Name, 1716 }, 1717 } 1718 Expect(k8sClient.Create(ctx, releasePlanAdmission)).Should(Succeed()) 1719 releasePlanAdmission.Kind = "ReleasePlanAdmission" 1720 1721 roleBinding = &rbac.RoleBinding{ 1722 ObjectMeta: metav1.ObjectMeta{ 1723 Name: "rolebinding", 1724 Namespace: "default", 1725 }, 1726 RoleRef: rbac.RoleRef{ 1727 APIGroup: rbac.GroupName, 1728 Kind: "ClusterRole", 1729 Name: "clusterrole", 1730 }, 1731 } 1732 Expect(k8sClient.Create(ctx, roleBinding)).To(Succeed()) 1733 1734 snapshot = &applicationapiv1alpha1.Snapshot{ 1735 ObjectMeta: metav1.ObjectMeta{ 1736 Name: "snapshot", 1737 Namespace: "default", 1738 }, 1739 Spec: applicationapiv1alpha1.SnapshotSpec{ 1740 Application: application.Name, 1741 }, 1742 } 1743 Expect(k8sClient.Create(ctx, snapshot)).To(Succeed()) 1744 snapshot.Kind = "Snapshot" 1745 } 1746 1747 deleteResources = func() { 1748 Expect(k8sClient.Delete(ctx, application)).To(Succeed()) 1749 Expect(k8sClient.Delete(ctx, component)).Should(Succeed()) 1750 Expect(k8sClient.Delete(ctx, enterpriseContractConfigMap)).Should(Succeed()) 1751 Expect(k8sClient.Delete(ctx, enterpriseContractPolicy)).Should(Succeed()) 1752 Expect(k8sClient.Delete(ctx, releasePlan)).To(Succeed()) 1753 Expect(k8sClient.Delete(ctx, releasePlanAdmission)).Should(Succeed()) 1754 Expect(k8sClient.Delete(ctx, releaseServiceConfig)).Should(Succeed()) 1755 Expect(k8sClient.Delete(ctx, snapshot)).To(Succeed()) 1756 } 1757 1758 })