github.com/oam-dev/kubevela@v1.9.11/pkg/webhook/core.oam.dev/v1beta1/application/validating_handler_test.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 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 application 18 19 import ( 20 . "github.com/onsi/ginkgo/v2" 21 . "github.com/onsi/gomega" 22 admissionv1 "k8s.io/api/admission/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/runtime" 25 "sigs.k8s.io/controller-runtime/pkg/webhook/admission" 26 ) 27 28 var _ = Describe("Test Application Validator", func() { 29 BeforeEach(func() { 30 Expect(handler.InjectClient(k8sClient)).Should(BeNil()) 31 Expect(handler.InjectDecoder(decoder)).Should(BeNil()) 32 }) 33 34 It("Test Application Validator [bad request]", func() { 35 req := admission.Request{ 36 AdmissionRequest: admissionv1.AdmissionRequest{ 37 Operation: admissionv1.Create, 38 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 39 Object: runtime.RawExtension{Raw: []byte("bad request")}, 40 }, 41 } 42 resp := handler.Handle(ctx, req) 43 Expect(resp.Allowed).Should(BeFalse()) 44 }) 45 46 It("Test Application Validator [Allow]", func() { 47 req := admission.Request{ 48 AdmissionRequest: admissionv1.AdmissionRequest{ 49 Operation: admissionv1.Create, 50 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 51 Object: runtime.RawExtension{ 52 Raw: []byte(` 53 {"apiVersion":"core.oam.dev/v1beta1", 54 "kind":"Application", 55 "metadata":{"name":"application-sample"}, 56 "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"}, 57 "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}} 58 `), 59 }, 60 }, 61 } 62 resp := handler.Handle(ctx, req) 63 Expect(resp.Allowed).Should(BeTrue()) 64 }) 65 66 It("Test Application Validator [Error]", func() { 67 req := admission.Request{ 68 AdmissionRequest: admissionv1.AdmissionRequest{ 69 Operation: admissionv1.Create, 70 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 71 Object: runtime.RawExtension{ 72 Raw: []byte(`{"apiVersion":"core.oam.dev/v1beta1", 73 "kind":"Application", 74 "metadata":{"name":"application-sample"}, 75 "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"}, 76 "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker1"}]}}`), 77 }, 78 }, 79 } 80 resp := handler.Handle(ctx, req) 81 Expect(resp.Allowed).Should(BeFalse()) 82 }) 83 84 It("Test Application Validator Forbid rollout annotation", func() { 85 req := admission.Request{ 86 AdmissionRequest: admissionv1.AdmissionRequest{ 87 Operation: admissionv1.Update, 88 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 89 Object: runtime.RawExtension{ 90 Raw: []byte(` 91 {"apiVersion":"core.oam.dev/v1beta1", 92 "kind":"Application", 93 "metadata":{"name":"application-sample", "annotations": {"app.oam.dev/rollout" : "true"},} 94 "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"}, 95 "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}} 96 `), 97 }, 98 OldObject: runtime.RawExtension{ 99 Raw: []byte(` 100 {"apiVersion":"core.oam.dev/v1beta1", 101 "kind":"Application", 102 "metadata":{"name":"application-sample"}, 103 "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"}, 104 "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}} 105 `), 106 }, 107 }, 108 } 109 resp := handler.Handle(ctx, req) 110 Expect(resp.Allowed).Should(BeFalse()) 111 }) 112 113 It("Test Application Validator workflow step name duplicate [error]", func() { 114 By("test duplicated step name in workflow") 115 req := admission.Request{ 116 AdmissionRequest: admissionv1.AdmissionRequest{ 117 Operation: admissionv1.Create, 118 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 119 Object: runtime.RawExtension{ 120 Raw: []byte(` 121 {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"suspend","type":"suspend"},{"name":"suspend","type":"suspend"}]}}} 122 `), 123 }, 124 }, 125 } 126 resp := handler.Handle(ctx, req) 127 Expect(resp.Allowed).Should(BeFalse()) 128 129 By("test duplicated sub step name in workflow") 130 req = admission.Request{ 131 AdmissionRequest: admissionv1.AdmissionRequest{ 132 Operation: admissionv1.Create, 133 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 134 Object: runtime.RawExtension{ 135 Raw: []byte(` 136 {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"step-group","subSteps":[{"name":"sub","type":"suspend"},{"name":"sub","type":"suspend"}]}]}}} 137 `), 138 }, 139 }, 140 } 141 resp = handler.Handle(ctx, req) 142 Expect(resp.Allowed).Should(BeFalse()) 143 144 By("test duplicated sub and parent step name in workflow") 145 req = admission.Request{ 146 AdmissionRequest: admissionv1.AdmissionRequest{ 147 Operation: admissionv1.Create, 148 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 149 Object: runtime.RawExtension{ 150 Raw: []byte(` 151 {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"step-group","subSteps":[{"name":"group","type":"suspend"},{"name":"sub","type":"suspend"}]}]}}} 152 `), 153 }, 154 }, 155 } 156 resp = handler.Handle(ctx, req) 157 Expect(resp.Allowed).Should(BeFalse()) 158 }) 159 160 It("Test Application Validator workflow step invalid timeout [error]", func() { 161 req := admission.Request{ 162 AdmissionRequest: admissionv1.AdmissionRequest{ 163 Operation: admissionv1.Create, 164 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 165 Object: runtime.RawExtension{ 166 Raw: []byte(` 167 {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"test"}]}}} 168 `), 169 }, 170 }, 171 } 172 resp := handler.Handle(ctx, req) 173 Expect(resp.Allowed).Should(BeFalse()) 174 }) 175 176 It("Test Application Validator workflow step invalid timeout [allow]", func() { 177 req := admission.Request{ 178 AdmissionRequest: admissionv1.AdmissionRequest{ 179 Operation: admissionv1.Create, 180 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"}, 181 Object: runtime.RawExtension{ 182 Raw: []byte(` 183 {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"1s"}]}}} 184 `), 185 }, 186 }, 187 } 188 resp := handler.Handle(ctx, req) 189 Expect(resp.Allowed).Should(BeTrue()) 190 }) 191 192 It("Test Application with empty policy", func() { 193 req := admission.Request{ 194 AdmissionRequest: admissionv1.AdmissionRequest{ 195 Operation: admissionv1.Create, 196 Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1beta1", Resource: "applications"}, 197 Object: runtime.RawExtension{ 198 Raw: []byte(` 199 {"kind":"Application","metadata":{"name":"app-with-empty-policy-webhook-test", "namespace":"default"}, 200 "spec":{"components":[],"policies":[{"name":"2345","type":"garbage-collect","properties":null}]}} 201 `), 202 }, 203 }, 204 } 205 resp := handler.Handle(ctx, req) 206 Expect(resp.Allowed).Should(BeFalse()) 207 }) 208 })