github.com/redhat-appstudio/release-service@v0.0.0-20240507045911-a8558ef3422a/api/v1alpha1/webhooks/releaseplanadmission/webhook_test.go (about) 1 // 2 // Copyright 2022 Red Hat, Inc. 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 package releaseplanadmission 17 18 import ( 19 . "github.com/onsi/ginkgo/v2" 20 . "github.com/onsi/gomega" 21 "github.com/redhat-appstudio/release-service/api/v1alpha1" 22 tektonutils "github.com/redhat-appstudio/release-service/tekton/utils" 23 "k8s.io/apimachinery/pkg/api/errors" 24 "k8s.io/apimachinery/pkg/types" 25 26 "github.com/redhat-appstudio/release-service/metadata" 27 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 //+kubebuilder:scaffold:imports 30 ) 31 32 var _ = Describe("ReleasePlanAdmission webhook", func() { 33 var releasePlanAdmission *v1alpha1.ReleasePlanAdmission 34 35 BeforeEach(func() { 36 releasePlanAdmission = &v1alpha1.ReleasePlanAdmission{ 37 TypeMeta: metav1.TypeMeta{ 38 APIVersion: "appstudio.redhat.com/v1alpha1", 39 Kind: "ReleasePlanAdmission", 40 }, 41 ObjectMeta: metav1.ObjectMeta{ 42 Name: "releaseplanadmission", 43 Namespace: "default", 44 }, 45 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 46 Applications: []string{"application"}, 47 Origin: "default", 48 Environment: "environment", 49 Pipeline: &tektonutils.Pipeline{ 50 PipelineRef: tektonutils.PipelineRef{ 51 Resolver: "bundles", 52 Params: []tektonutils.Param{ 53 {Name: "bundle", Value: "quay.io/some/bundle"}, 54 {Name: "name", Value: "release-pipeline"}, 55 {Name: "kind", Value: "pipeline"}, 56 }, 57 }, 58 }, 59 Policy: "policy", 60 }, 61 } 62 }) 63 64 AfterEach(func() { 65 err := k8sClient.Delete(ctx, releasePlanAdmission) 66 Expect(err == nil || errors.IsNotFound(err)).To(BeTrue()) 67 }) 68 69 When("a ReleasePlanAdmission is created without the auto-release label", func() { 70 It("should get the label added with its value set to true", func() { 71 Expect(k8sClient.Create(ctx, releasePlanAdmission)).Should(Succeed()) 72 Eventually(func() bool { 73 err := k8sClient.Get(ctx, types.NamespacedName{ 74 Name: releasePlanAdmission.Name, 75 Namespace: releasePlanAdmission.Namespace, 76 }, releasePlanAdmission) 77 78 labelValue, ok := releasePlanAdmission.GetLabels()[metadata.AutoReleaseLabel] 79 80 return err == nil && ok && labelValue == "true" 81 }, timeout).Should(BeTrue()) 82 }) 83 }) 84 85 When("a ReleasePlanAdmission is created with an invalid auto-release label value", func() { 86 It("should get rejected until the value is valid", func() { 87 releasePlanAdmission.Labels = map[string]string{metadata.AutoReleaseLabel: "foo"} 88 err := k8sClient.Create(ctx, releasePlanAdmission) 89 Expect(err).To(HaveOccurred()) 90 Expect(err.Error()).To(ContainSubstring("'%s' label can only be set to true or false", metadata.AutoReleaseLabel)) 91 }) 92 }) 93 94 When("a ReleasePlanAdmission is created with a valid auto-release label value", func() { 95 It("shouldn't be modified", func() { 96 By("setting label to true") 97 localReleasePlanAdmission := releasePlanAdmission.DeepCopy() 98 localReleasePlanAdmission.Labels = map[string]string{metadata.AutoReleaseLabel: "true"} 99 Expect(k8sClient.Create(ctx, localReleasePlanAdmission)).Should(Succeed()) 100 Eventually(func() bool { 101 err := k8sClient.Get(ctx, types.NamespacedName{ 102 Name: localReleasePlanAdmission.Name, 103 Namespace: localReleasePlanAdmission.Namespace, 104 }, localReleasePlanAdmission) 105 106 labelValue, ok := localReleasePlanAdmission.GetLabels()[metadata.AutoReleaseLabel] 107 108 return err == nil && ok && labelValue == "true" 109 }, timeout).Should(BeTrue()) 110 111 Expect(k8sClient.Delete(ctx, localReleasePlanAdmission)).To(Succeed()) 112 113 By("setting label to false") 114 localReleasePlanAdmission = releasePlanAdmission.DeepCopy() 115 localReleasePlanAdmission.Labels = map[string]string{metadata.AutoReleaseLabel: "false"} 116 Expect(k8sClient.Create(ctx, localReleasePlanAdmission)).Should(Succeed()) 117 Eventually(func() bool { 118 err := k8sClient.Get(ctx, types.NamespacedName{ 119 Name: localReleasePlanAdmission.Name, 120 Namespace: localReleasePlanAdmission.Namespace, 121 }, localReleasePlanAdmission) 122 123 labelValue, ok := localReleasePlanAdmission.GetLabels()[metadata.AutoReleaseLabel] 124 125 return err == nil && ok && labelValue == "false" 126 }, timeout).Should(BeTrue()) 127 }) 128 }) 129 130 When("a ReleasePlanAdmission is updated using an invalid auto-release label value", func() { 131 It("shouldn't be modified", func() { 132 Expect(k8sClient.Create(ctx, releasePlanAdmission)).Should(Succeed()) 133 releasePlanAdmission.GetLabels()[metadata.AutoReleaseLabel] = "foo" 134 err := k8sClient.Update(ctx, releasePlanAdmission) 135 Expect(err).To(HaveOccurred()) 136 Expect(err.Error()).To(ContainSubstring("'%s' label can only be set to true or false", metadata.AutoReleaseLabel)) 137 }) 138 }) 139 140 When("ValidateDelete method is called", func() { 141 It("should return nil", func() { 142 releasePlanAdmission := &v1alpha1.ReleasePlanAdmission{} 143 Expect(webhook.ValidateDelete(ctx, releasePlanAdmission)).To(BeNil()) 144 }) 145 }) 146 })